🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

2回答

1561閲覧

SQL での重複項目検索

m2677024688

総合スコア5

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/09/09 06:21

編集2019/09/09 08:27

前提・実現したいこと

SQLでの名前のあいまい検索で重複を探したいです。

バージョン

mysql
5.7.22

該当のソースコード

-- auto-generated definition create table table_name ( id int null, sei varchar(100) null, mei varchar(100) null ) charset = utf8mb4; insert table_name (id, sei, mei) VALUE (1, '田中', '二郎'); insert table_name (id, sei, mei) VALUE (2, '田中', '二郎2'); insert table_name (id, sei, mei) VALUE (3, '田中', '二郎3'); insert table_name (id, sei, mei) VALUE (4, '田中', '二郎4'); insert table_name (id, sei, mei) VALUE (5, '高橋', '太郎'); insert table_name (id, sei, mei) VALUE (6, '高橋', '太郎2'); insert table_name (id, sei, mei) VALUE (7, '高橋', '太郎3'); insert table_name (id, sei, mei) VALUE (8, '高橋', '太郎4'); insert table_name (id, sei, mei) VALUE (9, '斎藤2', '一郎9'); insert table_name (id, sei, mei) VALUE (10, '斎藤2', '一郎'); insert table_name (id, sei, mei) VALUE (11, '斎藤2', '一郎2'); insert table_name (id, sei, mei) VALUE (12, '斎藤2', '一郎3'); insert table_name (id, sei, mei) VALUE (13, '佐藤2', '四郎'); insert table_name (id, sei, mei) VALUE (14, '佐藤2', '四郎2'); insert table_name (id, sei, mei) VALUE (15, '佐藤2', '四郎3'); insert table_name (id, sei, mei) VALUE (16, '佐藤2', '四郎4'); insert table_name (id, sei, mei) VALUE (17, '佐藤2', '四郎5'); insert table_name (id, sei, mei) VALUE (18, '佐藤2', '四郎6'); SELECT CONCAT(sei, mei) as fullname FROM table_name GROUP BY fullname HAVING COUNT(*) > 1;

試したこと

SELECT CONCAT(sei, mei) as fullname, count(fullname) as count FROM table_name GROUP BY fullname HAVING COUNT(*) > 1;

期待値

idfullnamecount
1田中二郎4
10高橋2太郎4
1斎藤2一郎4
10佐藤2四郎5

・条件

sei : が完全一致 mei : 前方一致

上記の名前名前苗字が18レコードあることを確認できるようにしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/09/09 06:22

想定しているDBの種類(MySQL、PostgreSQLなど)とバージョンを質問に追記してください。 (DBの種類についてはタグ追加願います)
m.ts10806

2019/09/09 06:25

「あいまい検索」とのことですが、「こういうワードが来たらこういう内容を出したい」といった風にサンプルデータと期待する結果を具体的に書かれた方が良いと思います。 fullnameをlikeで検索してcount()ではダメなのか、とか。
m2677024688

2019/09/09 06:39

できるのでしょうか?
m.ts10806

2019/09/09 06:41

何かしら検索ワードを投入するわけではないということですね
m2677024688

2019/09/09 06:42

はいそうなります。 あいまいで申し訳ありませんが、上記のような2レコードを出すことが目標です。
m.ts10806

2019/09/09 06:44

できるかどうかはかなり捻りが必要には思います。 「あいまい検索」というワードは何かべつの表現に変えたほうが良いと思います。 大抵は何かしらキーワードが投入されることを期待します。
m2677024688

2019/09/09 06:45 編集

なるほどですね。 今回のしたいことは重複データで似た名前の人を全て抽出したいです。
m.ts10806

2019/09/09 06:52

「似た」というと結構それこそあいまいになってしまいますね。 例示だと苗字だけ一致する人・・・?か名前+苗字1文字目が一致 とかになるかもしれませんけど、 法則性を決める必要があると思います。 2名前苗字 だとどうなるかとか、こちらとしてはもっとパターンが欲しいですし、法則も詰められたほうが良いと思います。 プログラムは書いた通りにしか動かないので、仕様をしっかり決めて書かないとイレギュラーパターンで泣くことになります。
m.ts10806

2019/09/09 06:53

あごめんなさい。下記ですね。 sei : が完全一致 mei : 部分一致
m2677024688

2019/09/09 07:15

sqlでは限界がある気がしています。 プログラムで実行しようかと思っています。
m.ts10806

2019/09/09 07:26

というよりmeiの「部分一致」がネックです。 前方一致、後方一致ならまだやりやすいかもしれませんが、「部分一致」となるとそれこそ「苗字だけ合ってればOK」ということにもなりえます。 ここは「どの程度の部分一致を許容するのか」の要件を詰めないとプログラム側でもどうにもできないと思います。
m2677024688

2019/09/09 08:21

自分もそのように定義があいまいだったため、前方一致で進めることにしました。 良い方法はありますでしょうか?
m.ts10806

2019/09/09 08:24

となると「どこまで許容するか」を詰めていく必要があります。 何文字まで合ってればよいのか 太郎と太朗は同じとするのか。太朗太と太郎太は同じとするのか・・とか。 ここは「決め」になってきますので、やはり仕様を詰めるしかないと思います。 近似値を求めるのは数字は割と楽ですが文字となるとかなり困難になると思います。 もっと言えば「これを実現して何がしたいのか」という大目的部分も詰める必要がありそうです。
guest

回答2

0

やりたいことは、FULLTEXTのMATCH AGAINSTな気もしますが、
テーブル仕様が違うので、今回の条件内で、行う場合。

SQL

1SELECT T1.id 2 , T1.sei 3 , T1.mei 4 , ( 5 SELECT COUNT( 'X' ) 6 FROM table_name T3 7 WHERE T3.sei = T1.sei 8 AND T3.mei like concat( '%' 9 , ifnull(SUBSTR(T1.mei,1,1), '' ) 10 , '%' 11 , ifnull(SUBSTR(T1.mei,2,1), '' ) 12 , '%' 13 , ifnull(SUBSTR(T1.mei,3,1), '' ) 14 , '%' 15 , ifnull(SUBSTR(T1.mei,4,1), '' ) 16 , '%' 17 , ifnull(SUBSTR(T1.mei,5,1), '' ) 18 , '%' 19 , ifnull(SUBSTR(T1.mei,6,1), '' ) 20 ) 21 ) as cnt 22FROM table_name T1 23WHERE EXISTS( 24 SELECT 'X' 25 FROM table_name T2 26 WHERE T2.id <> T1.id 27 AND T2.sei = T1.sei 28 AND T2.mei like concat( '%' 29 , ifnull(SUBSTR(T1.mei,1,1), '' ) 30 , '%' 31 , ifnull(SUBSTR(T1.mei,2,1), '' ) 32 , '%' 33 , ifnull(SUBSTR(T1.mei,3,1), '' ) 34 , '%' 35 , ifnull(SUBSTR(T1.mei,4,1), '' ) 36 , '%' 37 , ifnull(SUBSTR(T1.mei,5,1), '' ) 38 , '%' 39 , ifnull(SUBSTR(T1.mei,6,1), '' ) 40 ) 41 )

実行結果

idseimeicnt
1田中二郎4
5高橋太郎4
10斎藤2一郎4
13佐藤2四郎6

ちなみに、高橋2なんて結果は出ませんし、佐藤2四朗も6ですよね?
机上の期待値はよく確認してくださいね。

投稿2019/09/30 21:46

tomari_perform

総合スコア760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まず「名前苗字:9」「名前2苗字:9」にはならない。8:10です
またグループ処理をしたらどのidをひろうか指定しないとだめ
一番小さいのでよいのでしょうか?

SQL

1select min(id) as id,concat(sei,'苗字') as fullname,count(*) as cnt from table_name 2where mei like '苗字%' 3group by fullname 4order by id

sample

  • 元データ

SQL

1create table tbl( 2 id int primary key, 3 sei varchar(100) null, 4 mei varchar(100) null 5); 6insert into tbl (id, sei, mei) VALUE 7(1, '田中', '二郎'), 8(2, '田中', '二郎2'), 9(3, '田中', '二郎3'), 10(4, '田中', '二郎4'), 11(5, '高橋', '太郎'), 12(6, '高橋', '太郎2'), 13(7, '高橋', '太郎3'), 14(8, '高橋', '太郎4'), 15(9, '斎藤2', '一郎9'), 16(10, '斎藤2', '一郎'), 17(11, '斎藤2', '一郎2'), 18(12, '斎藤2', '一郎3'), 19(13, '斎藤2', '一'), 20(14, '斎藤2', '一二三'), 21(15, '斎藤2', '二郎');
  • 抽出
select min(id) as id,concat(sei,substr(mei,1,1)) as fullname,count(*) as cnt from tbl group by fullname order by id

投稿2019/09/09 07:45

編集2019/09/09 09:35
yambejp

総合スコア116661

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m2677024688

2019/09/09 08:22

上記のはサンプルの名前のため苗字%などが使えない状態です。
yambejp

2019/09/09 08:27 編集

一部とはなにかが多分理解できていないのでしょう 小-小山-小山田とあったとき小%と小山%では違う集計です つまり質問者さんのやろうとしていることは机上の空論なので SQLでやることではありません もう少しいろんなパターンを含んだサンプルで考え方をまとめてから 質問されるとよいでしょう
yambejp

2019/09/09 08:58

斎藤が「一郎」だとして 「一二三」がいたら「一」で一緒になるので一緒なの? つまり1文字目だけあってればよいのでしょうか?
m2677024688

2019/09/09 09:09

はい。 その認識であっております。
yambejp

2019/09/09 09:35 編集

じゃ、斎藤は「斎藤2一」なんですね? sample確認ください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問