2011-08-11 28 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