2017-03-08 75 views
1

使用MySQL,我試圖計算每列中子字符串出現次數。MySQL計算列中子字符串出現次數

在下面的示例表,字符串「藝術」出現在條款柱三次,所以它必須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 
+0

請與我們分享您的試驗。 –

+0

你的替換函數用它自己替換每一行的術語;在我的答案中看看建議1和2。 – MohaMad

回答

2

我會先寫一個查詢,只是返回我們要返回術語列表寫這篇文章。例如:

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

的查詢可以修改,以符合僅出現在開始的其他termsterms

隨訪

隨着數據。例如,返回:

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

非常好的答案!但是在'ORDER BY'之前你不需要'GROUP BY w.term'嗎? –

+1

@MichaelK:是的。我們確實需要一個GROUP BY。 * DOH!*(回答編輯包含更正。) – spencer7593

+0

當我學習新事物時喜歡它..優雅的解決方案 –

相關問題