前提・実現したいこと
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;
期待値
| id | fullname | count |
|---|---|---|
| 1 | 田中二郎 | 4 |
| 10 | 高橋2太郎 | 4 |
| 1 | 斎藤2一郎 | 4 |
| 10 | 佐藤2四郎 | 5 |
・条件
sei : が完全一致 mei : 前方一致
上記の名前名前苗字が18レコードあることを確認できるようにしたいです。
想定しているDBの種類(MySQL、PostgreSQLなど)とバージョンを質問に追記してください。
(DBの種類についてはタグ追加願います)
mysql 5.7.22です。
「あいまい検索」とのことですが、「こういうワードが来たらこういう内容を出したい」といった風にサンプルデータと期待する結果を具体的に書かれた方が良いと思います。
fullnameをlikeで検索してcount()ではダメなのか、とか。
できるのでしょうか?
何かしら検索ワードを投入するわけではないということですね
はいそうなります。
あいまいで申し訳ありませんが、上記のような2レコードを出すことが目標です。
できるかどうかはかなり捻りが必要には思います。
「あいまい検索」というワードは何かべつの表現に変えたほうが良いと思います。
大抵は何かしらキーワードが投入されることを期待します。
なるほどですね。
今回のしたいことは重複データで似た名前の人を全て抽出したいです。
「似た」というと結構それこそあいまいになってしまいますね。
例示だと苗字だけ一致する人・・・?か名前+苗字1文字目が一致 とかになるかもしれませんけど、
法則性を決める必要があると思います。
2名前苗字 だとどうなるかとか、こちらとしてはもっとパターンが欲しいですし、法則も詰められたほうが良いと思います。
プログラムは書いた通りにしか動かないので、仕様をしっかり決めて書かないとイレギュラーパターンで泣くことになります。
あごめんなさい。下記ですね。
sei : が完全一致
mei : 部分一致
sqlでは限界がある気がしています。
プログラムで実行しようかと思っています。
というよりmeiの「部分一致」がネックです。
前方一致、後方一致ならまだやりやすいかもしれませんが、「部分一致」となるとそれこそ「苗字だけ合ってればOK」ということにもなりえます。
ここは「どの程度の部分一致を許容するのか」の要件を詰めないとプログラム側でもどうにもできないと思います。
自分もそのように定義があいまいだったため、前方一致で進めることにしました。
良い方法はありますでしょうか?
となると「どこまで許容するか」を詰めていく必要があります。
何文字まで合ってればよいのか
太郎と太朗は同じとするのか。太朗太と太郎太は同じとするのか・・とか。
ここは「決め」になってきますので、やはり仕様を詰めるしかないと思います。
近似値を求めるのは数字は割と楽ですが文字となるとかなり困難になると思います。
もっと言えば「これを実現して何がしたいのか」という大目的部分も詰める必要がありそうです。