我會先寫一個查詢,只是返回我們要返回術語列表寫這篇文章。例如:
SELECT t.terms
FROM `table` t
GROUP BY t.terms
然後包裹在括號並用它作爲內嵌視圖...
SELECT w.terms
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
ORDER BY w.terms
這樣,我們可以做一個連接操作來尋找匹配的行,並獲得了計數。假設terms
不包含下劃線(_
)或百分比(%
)字符的保證,我們可以使用LIKE
比較。
鑑於我們列表中的每個術語至少會出現一次,我們可以使用內部聯接。在更一般的情況下,我們可能希望返回零計數,我們將使用外連接。
SELECT w.terms
, COUNT(1) AS `COUNT`
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
JOIN `table` c
ON c.terms LIKE CONCAT('%', w.terms ,'%')
GROUP BY w.terms
ORDER BY w.terms
在LIKE
比較,百分號是通配符匹配任何字符(零個,一個或更多)。
如果有可能terms
確實包含下劃線或百分號字符,我們可以將它們轉義,以便它們不被LIKE比較視爲通配符。像這樣的表達應該做的伎倆:
REPLACE(REPLACE(w.terms ,'_','\_'),'%','\%')
所以我們不得不這樣的查詢:
SELECT w.terms
, COUNT(1) AS `COUNT`
FROM (SELECT t.terms
FROM `table` t
GROUP BY t.terms
) w
JOIN `table` c
ON c.terms LIKE CONCAT('%',REPLACE(REPLACE(w.terms ,'_','\_'),'%','\%'),'%')
GROUP BY w.terms
ORDER BY w.terms
還有其他的查詢模式,將返回指定的結果。這只是一種方法的演示。
注意:在這個問題的例子,每一個terms
那是另一個terms
一子,子字符串匹配出現在開始術語。此查詢還會查找匹配項不在開頭的位置。
例如dartboard
將被視爲匹配art
的查詢可以修改,以符合僅出現在開始的其他terms
terms
。
隨訪
隨着數據。例如,返回:
terms COUNT matched_terms
--------- -------- -------------------------
art 3 art,art deco,artistic
art deco 1 art deco
artistic 1 artistic
elephant 1 elephant
paint 3 paint,painting,paintings
painting 2 painting,paintings
paintings 1 paintings
除了COUNT(1)
骨料,我還包括在選擇列表中的另一種表達。這不是必需的,但它確實提供了關於哪些術語被認爲是匹配的一些附加信息。
GROUP_CONCAT(DISTINCT c.terms ORDER BY c.terms) AS `matched_terms`
注意:如果有一種可能性,即terms
包含反斜槓字符,就可以逃避這些字符以及使用替換另一個
REPLACE(REPLACE(REPLACE(w.terms ,'\\','\\\\'),'_','\_'),'%','\%')
^^^^^^^^ ^^^^^^^^^^^^^
請與我們分享您的試驗。 –
你的替換函數用它自己替換每一行的術語;在我的答案中看看建議1和2。 – MohaMad