質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

2回答

3663閲覧

名寄せ機能の実装に関して (MYSQL)

techtottori

総合スコア26

MySQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

1クリップ

投稿2017/10/12 07:23

編集2017/10/12 07:45

###前提・実現したいこと
MYSQLを使って名寄せ(重複項目の統合)を行いたいです。
ですが、データベースの初心者であるため、どう行えば良いかわかりません。

条件としては、主キー(id)
nayose_otameshi テーブルに4つのカラム
first_name_kana,
last_name_kana,
phone_number,
city
の項目の名寄せを行いたいです。
現状としては、下記の用に記載したのですが、うまくプログラムが動きません。
お力をお貸しいただけないでしょうか?

SELECT * FROM nayose_otameshi r1 WHERE EXISTS(SELECT * FROM nayose_otameshi r2 WHERE r1.first_name_kana = r2.first_name_kana AND r1.last_name_kana = r2.last_name_kana AND r1.phone_number = r2.phone_number AND r1.city = r2.city ) ;

エラーメッセージ

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'r1 WHERE EXISTS(SELECT * FROM nayose_otameshi r2 ' at line 1

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/10/12 07:41 編集

「うまくプログラムが動きません」とはどういう状態でしょうか。結果が1行も得られないのか、何かしらのエラーメッセージが表示されるのか。もう少し詳しく教えて下さい。というかそもそも同じテーブルで突き合わせすると必ず同じレコードが存在するので、全く名寄せにならない気がしますが。
techtottori

2017/10/12 07:46

すいません。上記は抽出になってしまっていますが、やりたいこととしては、テーブルの中の名寄せを行いたいです。
退会済みユーザー

退会済みユーザー

2017/10/12 08:13

名寄せって、一般的には、表記のゆらぎもある程度吸収する作りになっていると思いますが、その辺のポリシーはどのように考えているのでしょうか?
techtottori

2017/10/12 08:27

重複項目の統合をメインに考えています。NULL項目は基本的にないです。
退会済みユーザー

退会済みユーザー

2017/10/12 08:47

4項目の完全一致のみを確認すれば良いって感じですかね?半角全角の混在や余計なスペース、ハイフンやズとヅのような同音異表記と言ったモノは考慮外であるってことで。
techtottori

2017/10/12 08:53

とりあえず、現状そういう認識であっております。
guest

回答2

0

とりあえず抽出したいのであれば

SELECT first_name_kana,last_name_kana,phone_number,city FROM nayose_otameshi GROUP BY first_name_kana,last_name_kana,phone_number,city HAVING count(*)>1

とするだけでよいかと思います

sample

SQL

1create table nayose_otameshi(id int primary key auto_increment, 2first_name_kana varchar(10), 3last_name_kana varchar(10), 4phone_number varchar(10), 5city varchar(10)); 6 7insert into nayose_otameshi(first_name_kana,last_name_kana,phone_number,city) values 8('f1','l1','p1','c1'), 9('f2','l2','p2','c2'), 10('f2','l2','p2','c2'), 11('f3','l3','p3','c3'), 12('f1','l4','p4','c4'), 13('f1','l1','p1','c1'), 14('f3','l3','p3','c3'), 15('f2','l2','p2','c2');

上記のように別途主キーが設定されているのであれば2番め以降に出て来るレコードはこう

SQL

1select id from nayose_otameshi as t1 2where exists(select 1 from nayose_otameshi as t2 3where 1 4and t1.first_name_kana=t2.first_name_kana 5and t1.last_name_kana=t2.last_name_kana 6and t1.phone_number=t2.phone_number 7and t1.city=t2.city 8and t1.id>t2.id 9)

id=3,6,7,8が抽出されるのでこれを利用して削除

SQL

1delete from nayose_otameshi 2where id in( 3select id from( 4select id from nayose_otameshi as t1 5where exists(select 1 from nayose_otameshi as t2 6where 1 7and t1.first_name_kana=t2.first_name_kana 8and t1.last_name_kana=t2.last_name_kana 9and t1.phone_number=t2.phone_number 10and t1.city=t2.city 11and t1.id>t2.id 12) 13)as temp 14)

deleteに自己結合したデータはダイレクトにつかえないので
一度ダミーのサブクエリでselectを抽出しないといけません

投稿2017/10/12 07:41

編集2017/10/12 08:19
yambejp

総合スコア114572

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

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

0

ベストアンサー

不必要に複雑に考えているかもしれませんが、idを取得できるように考えてみました。

SQL

1SELECT 2 r1.id id1 3 , concat(r1.first_name_kana, ' ', r1.last_name_kana) name1 4 , r2.id id2 5 , concat(r2.first_name_kana, ' ', r2.last_name_kana) name2 6FROM 7 ( 8 SELECT 9 MIN(id) id 10 , first_name_kana 11 , last_name_kana 12 , phone_number 13 , city 14 FROM 15 nayose_otameshi 16 GROUP BY 17 first_name_kana 18 , last_name_kana 19 , phone_number 20 , city 21 ) r1 22 INNER JOIN nayose_otameshi r2 23 ON r1.first_name_kana = r2.first_name_kana 24 AND r1.last_name_kana = r2.last_name_kana 25 AND r1.phone_number = r2.phone_number 26 AND r1.city = r2.city 27 AND r1.id < r2.id 28order by 29 id1, id2;

追記:

削除まで一気にやるとするならこうでしょうか。

DELETE FROM nayose_otameshi WHERE nayose_otameshi.id IN ( SELECT tmp.id FROM ( SELECT r2.id FROM ( SELECT MIN(id) id , first_name_kana , last_name_kana , phone_number , city FROM nayose_otameshi GROUP BY first_name_kana , last_name_kana , phone_number , city ) r1 INNER JOIN nayose_otameshi r2 ON r1.first_name_kana = r2.first_name_kana AND r1.last_name_kana = r2.last_name_kana AND r1.phone_number = r2.phone_number AND r1.city = r2.city AND r1.id < r2.id ) as tmp );

投稿2017/10/12 07:46

編集2017/10/12 08:00
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

techtottori

2017/10/12 07:51

回答ありがとうございます。 抽出して削除(統合)するところまで考えているのですが、わかりますでしょうか?
techtottori

2017/10/12 08:27

迅速な対応ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問