2016-08-12 42 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距離」。數據庫可能有一個實現。 –

+1

我幫助了一些格式化,但刪除了很多nbsp; -s仍然適合您。 – peterh

回答

1

只是爲了好玩,這裏的一些樣品的Postgres的戈登提到萊文施泰因代碼(RDBMS您使用哪一個?),但問題並非如此簡單。

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 

返回

"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 

但是,現在你必須做這些距離的東西(在過去的山坳數)。數字越大,距離越大,距離越小,越不相似。因此,您可以輕鬆創建一個將每個字符串綁定到分數的查找表,但是最終會導致項目落在多個組中,因此不能真正實現分組。根據你有多少數據,你可以把它拉出來,用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

'紅熱(加州居住)'不像'紅辣椒'。另外不建議使用'mysql_ *'。 – chris85

+0

我刪除了mysql_ *,我更喜歡PDO。 @ chris85 –

+4

@ chris85有*沒有'LIKE'紅辣椒!* ;-) –