[英]MySQL Count number of substring occurrences in column
使用MySQL,我試圖計算每一行中一個子串的出現次數。
在下面的示例表中,字符串“art”在“條款”列中出現三次,因此它的計數為3。
示例表:
TERMS
art
artistic
painting
elephant
art deco
paint
paintings
期望的輸出:
TERMS COUNT
art 3
artistic 1
painting 2
elephant 1
art deco 1
paint 2
paintings 1
編輯:
作為一個起點,我知道:
SELECT terms, COUNT(*)
FROM table
GROUP BY terms
將輸出每個完整術語字符串的出現次數。 對於子字符串匹配,我認為這可能涉及子查詢。
試過以下,但每個計數都是1。
SELECT terms, ROUND((CHAR_LENGTH(terms) - CHAR_LENGTH(REPLACE(terms, terms, ""))) / CHAR_LENGTH(terms)) AS count
FROM table
GROUP BY terms
我會寫這個,首先編寫一個只返回我們想要返回的術語列表的查詢。 例如:
SELECT t.terms
FROM `table` t
GROUP BY t.terms
然后將其包裝在parens中並將其用作內聯視圖...
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(REPLACE( w.terms ,'\\','\\\\'),'_','\_'),'%','\%')
^^^^^^^^ ^^^^^^^^^^^^^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.