2016-08-12 9 views
0

表には数千もの人気のある音楽バンドがあり、これらの名前はさまざまな方法で書き込むことができます。たとえば、次のようにSQLテーブルの列に類似のフレーズをグループ化するにはどうすればいいですか?

  • 「ハンガリーのレッド・ホット・チリ・ペッパーズ」
  • 「コンサートレッド・ホット・チリ・ペッパーズ」
  • 「レッド・ホット・チリ・ペッパーズ」
  • 「レッドホット(CAにライブ)」

各行にフィールドgroup_idがあります。この分野はすべての類似アーティストにとって同じでなければなりません。たとえば、グループの中で最も小さいID:

id | name         | group_id 
------------------------------------------------------- 
1137 | "Red Hot Chili Peppers in Hungary" | 1137 
1138 | "Concert Red Hot Chili Peppers"  | 1137 
1139 | "Red Hot Chili Peppers"    | 1137 
1140 | "Red Hot (Live in CA)"    | 1137 

は今は、すべての行で空をGROUP_ID。どのように正しく似たような名前を組み合わせて割り当てますか?group_id?例えば

+0

質問の文脈で「類似」の定義をより正確に指定できますか? –

+1

Google: "Levenshtein distance"たぶんあなたのデータベースのための実装があります。 –

+1

少し書式設定を手伝ってくれましたが、たくさんのnbsp; -sは削除されています。 – peterh

答えて

1

楽しみのためだけに、ここでゴードンが述べたように、いくつかのサンプルPostgresのコードがlevensteinのために(?あなたが使用しているRDBMS)ですが、問題はそれほど単純ではありません。

"Red Hot Chili Peppers in Hungary";"Concert Red Hot Chili Peppers";19 
"Red Hot Chili Peppers in Hungary";"Red Hot Chili Peppers";11 
"Red Hot Chili Peppers in Hungary";"Red Hot (Live in CA)";18 
"Concert Red Hot Chili Peppers";"Red Hot Chili Peppers";8 
"Concert Red Hot Chili Peppers";"Red Hot (Live in CA)";19 
"Red Hot Chili Peppers";"Red Hot (Live in CA)";11 

を返し

create extension fuzzystrmatch 

create table t (id serial, txt text) 
insert into t(txt) values('Red Hot Chili Peppers in Hungary'); 
insert into t(txt) values('Concert Red Hot Chili Peppers'); 
insert into t(txt) values('Red Hot Chili Peppers'); 
insert into t(txt) values('Red Hot (Live in CA)'); 

select a.txt a, b.txt b, levenshtein(a.txt, b.txt) from t as a inner join t as b on a.id < b.id 

しかし、今、あなたはこれらの距離(最後のCOLで数)で何かをしなければなりません。数値が大きいほど距離は大きくなりますが、距離が大きいほど距離は小さくなります。したがって、各文字列をスコアにバインドするルックアップテーブルを簡単に作成することはできますが、多くのグループに分類されるアイテムになりますので、実際にグループ化することはできません。

データの量に応じて、KMeansのようなものでクラスターを作成し、それを元に戻したり、既知のグループのリストを維持したりすることができます。グループによっては、まだ多くのグループで行が残っている可能性があります。

とにかく、楽しんでください、これは、興味深い問題に役立つことを願っています。

+0

levensteinはすごいです –

0

あなたのグループがgroup_nameが含まれている場合は、これはあなたにその特定のグループ名を含むすべての結果が得られます。この

SELECT * 
FROM `table` 
WHERE `column` LIKE '%{$group_name}%' 

ような何かを行うことができます。この節でもUPDATEを実行できます。

UPDATE groups 
SET group_id=1771 
WHERE `column` LIKE '%{$group_name}%' 
+1

'Red Hot(Live in CA)は' Red Hot Chili Peppers 'のようなものではない。また、mysql_ *の使用について助言しないでください。 – chris85

+0

私はmysql_ *を削除しましたが、PDOも好きです。 @ chris85 –

+4

@ chris85レッド・ホット・チリ・ペッパーズは何も「好き」ではない!* ;-) –

関連する問題