所以我的问题非常简单:
我在SQL中有一个以逗号分隔列表的列(即cats,dogs,cows,
)我需要使用 only sql来计算其中的项目数(所以无论我的功能是什么(让我们现在称之为fx)就像这样:
SELECT fx(fooCommaDelimColumn) AS listCount FROM table WHERE id=...
我知道这是有缺陷的,但你明白了(如果fooCommaDelimColumn
的值是cats,dogs,cows,
,则BTW,那么listCount应该返回4 ...)。
就是这样。
答案 0 :(得分:47)
没有内置函数可以计算字符串中子字符串的出现次数,但是您可以计算原始字符串与没有逗号的相同字符串之间的差异:
LENGTH(fooCommaDelimColumn) - LENGTH(REPLACE(fooCommaDelimColumn, ',', ''))
它在近8年的时间里被编辑了多次(哇!),所以为了清楚起见:上面的查询不需要+ 1
,因为OP数据有一个额外的尾随逗号。< / p>
实际上,对于看起来像这样的字符串的一般情况:foo,bar,baz
正确的表达式将是
LENGTH(col) - LENGTH(REPLACE(col, ',', '')) + 1
答案 1 :(得分: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;
答案 2 :(得分: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
我也同意重构表格是最好的选择,但如果现在不能这样做,那么这个代码片段可以完成这项工作。
答案 3 :(得分:3)
此版本不支持前导或尾随逗号,但支持计数为0的空值:
IF(values, LENGTH(values) - LENGTH(REPLACE(values, ',', '')) + 1, 0) AS values_count
答案 4 :(得分:1)
如果我们执行+1,并且如果我们有一个空列,那么它总是以1表示为0,则可以在mySQL中使用IF条件。
IF(LENGTH(column_name) > 0, LENGTH(column_name) - LENGTH(REPLACE(column_name, ',', '')) + 1, 0)
答案 5 :(得分:0)
答案是更正数据库架构。这听起来像是一对多关系,需要一个联结表。 http://en.wikipedia.org/wiki/Junction_table