2011-08-11 33 views
13

所以我的問題很簡單:如何計算以逗號分隔的列表MySQL的項目

我在SQL列是一個逗號分隔的列表(即cats,dogs,cows,)我需要使用計數在它的項目數只有 SQL(所以不管我的功能是(讓稱之爲FX現在)會的工作是這樣的:

SELECT fx(fooCommaDelimColumn) AS listCount FROM table WHERE id=... 

我知道這是有缺陷的,但你的想法(BTW如果fooCommaDelimColumncats,dogs,cows,,那麼listCount應該返回4 ...)。

就是這樣。

+0

這個線程也已經回答了[這裏](https://開頭計算器。com/questions/5033047/mysql-query-finding-values-in-a-comma-separated-string/47069224)#47069224) – Delickate

回答

38

有計數子的出現次數字符串中沒有內置的功能,但你可以計算出原始字符串之間以及相同的字符串沒有逗號的差別,:

LENGTH(fooCommaDelimColumn) - LENGTH(REPLACE(fooCommaDelimColumn, ',', '')) 
+0

雖然這可行,但如果托馬斯沒有正確建模是數據庫。 –

+6

實際上,如果列表中只有一個項目,您應該添加1:LENGTH(fooCommaDelimColumn) - LENGTH(REPLACE(fooCommaDelimColumn,',',''))+ 1.這仍然值得+1原則表達。 – RolandoMySQLDBA

+0

@RolandoMySQLDBA:我以爲同樣的事情,但托馬斯的字符串包括一個尾隨逗號,所以它不是必需的。 –

6

zerkms的解決方案的工作,毫無疑問。正如Steve Wellens指出的那樣,您的問題是由不正確的數據庫模式造成的。一列中不應有多個值,因爲它違反了第一條正常法則。相反,你至少應該製作兩張桌子。舉例來說,假設你有成員誰擁有動物

table member (member_id, member_name) 
table member_animal (member_id, animal_name) 

更妙的是:因爲許多用戶可以有相同類型的動物,你應該創建3個表:

table member (member_id, member_name) 
table animal (animal_id, animal_name) 
table member_animal (member_id, animal_id) 

你可以填充你的表是這樣,例如:

member (1, 'Tomas') 
member (2, 'Vincent') 
animal (1, 'cat') 
animal (2, 'dog') 
animal (3, 'turtle') 
member_animal (1, 1) 
member_animal (1, 3) 
member_animal (2, 2) 
member_animal (2, 3) 

而且,回答你最初的問題,這就是,如果你想知道每個用戶有多少動物有,你會做什麼:

SELECT member_id, COUNT(*) AS num_animals 
FROM member 
INNER JOIN member_animal 
    USING (member_id) 
INNER JOIN animal 
    USING (animal_id) 
GROUP BY member_id; 
+0

事實上,這個答案更*正確*。在這裏,我們將互相幫助,以正確的方式執行,以解決問題的根源,+1 – zerkms

+0

感謝您的幫助,我仍然樂於接觸一些學習資源,但(如您所見我的sql知識以UPDATE結束:)) – Tomas

4

繼從@zerkms的建議。

如果你不知道是否有尾隨逗號或不使用TRIM功能,以消除任何尾隨逗號:

(
    LENGTH(TRIM(BOTH ',' FROM fooCommaDelimColumn)) 
    - LENGTH(REPLACE(TRIM(BOTH ',' FROM fooCommaDelimColumn), ',', '')) 
    + 1 
) as count 

參考:http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_trim

我也同意,表的重構是最好的選擇,但如果現在不可能,這段代碼可以完成這項工作。

+0

這是全面的解決方案。有時需要以JSON編碼形式(例如'[「ABC」,「DEF」,「GHI」,「JKL」)')存儲數據(數組),並且還需要對內部的項進行計數。爲此,您的解決方案即使沒有*修剪*也能正常工作。 – shadyyx

2

此版本不支持開頭或結尾逗號,但支持空值與計數0:

IF(values, LENGTH(values) - LENGTH(REPLACE(values, ',', '')) + 1, 0) AS values_count