簡體   English   中英

MySQL計算列中子字符串出現次數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM