简体   繁体   English

如何计算逗号分隔列表 MySQL 中的项目

[英]How to count items in comma separated list MySQL

So my question is pretty simple:所以我的问题很简单:

I have a column in SQL which is a comma separated list (ie cats,dogs,cows, ) I need to count the number of items in it using only sql (so whatever my function is (lets call it fx for now) would work like this:我在 SQL 中有一个列,它是一个逗号分隔的列表(即cats,dogs,cows, )我需要使用 sql 来计算其中的项目数(所以无论我的 ZC1C425268E68385D1AB5074C1 现在如何称呼它 fxA941 都可以)像这样:

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

I know that that is flawed, but you get the idea (BTW if the value of fooCommaDelimColumn is cats,dogs,cows, , then listCount should return 4...).我知道这是有缺陷的,但你明白了(顺便说一句,如果fooCommaDelimColumn的值是cats,dogs,cows,那么 listCount 应该返回 4...)。

That is all.就这些。

There is no built-in function that counts occurences of substring in a string, but you can calculate the difference between the original string, and the same string without commas:没有内置的 function 可以计算字符串中 substring 的出现次数,但是您可以计算原始字符串与不带逗号的同一字符串之间的差异:

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

It was edited multiple times over the course of almost 8 years now (wow,): so for sake of clarity: the query above does not need a + 1 , because OPs data has an extra trailing comma.它在近 8 年的时间里被多次编辑(哇,):所以为了清楚起见:上面的查询不需要+ 1 ,因为 OPs 数据有一个额外的尾随逗号。

While indeed, in general case for the string that looks like this: foo,bar,baz the correct expression would be虽然确实,对于看起来像这样的字符串,一般情况下: foo,bar,baz正确的表达式是

LENGTH(col) - LENGTH(REPLACE(col, ',', '')) + 1

zerkms' solution works, no doubt about that. zerkms 的解决方案有效,这一点毫无疑问。 But your problem is created by an incorrect database schema, as Steve Wellens pointed out.但是正如 Steve Wellens 指出的那样,您的问题是由不正确的数据库模式造成的。 You should not have more than one value in one column because it breaks the first normal law.一个列中不应有多个值,因为它违反了第一条正常定律。 Instead, you should make at least two tables.相反,您应该至少制作两张桌子。 For instance, let's say that you have members who own animals :例如,假设您有拥有动物成员

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

Even better: since many users can have the same type of animal, you should create 3 tables:更好的是:由于许多用户可以拥有相同类型的动物,您应该创建 3 个表:

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

You could populate your tables like this, for instance:您可以像这样填充您的表格,例如:

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)

And, to answer your initial question, this is what you would do if you wanted to know how many animals each user has:而且,为了回答你最初的问题,如果你想知道每个用户有多少只动物,你会这样做:

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;

Following the suggestion from @zerkms.根据@zerkms 的建议。

If you dont know if there is a trailing comma or not, use the TRIM function to remove any trailing commas:如果您不知道是否有尾随逗号,请使用 TRIM function 删除任何尾随逗号:

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

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

I also agree that a refactoring of the tables is the best option, but if this is not possible now, this snippet can do the work.我也同意重构表是最好的选择,但如果现在不可能,这个片段可以完成工作。

This version doesn't support leading or trailing commas, but supports an empty value with a count of 0:此版本不支持前导或尾随逗号,但支持计数为 0 的空值:

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

If we do +1 and if we have an empty column it always comes as 1 to make it 0 we can use IF condition in mySQL.如果我们做 +1 并且如果我们有一个空列,它总是作为 1 使其成为 0,我们可以在 mySQL 中使用 IF 条件。

IF(LENGTH(column_name) > 0, LENGTH(column_name) - LENGTH(REPLACE(column_name, ',', '')) + 1, 0)

The answer is to correct the database schema.答案是更正数据库模式。 It sounds like a many-to-many relationship which requires a junction table.这听起来像是一个需要连接表的多对多关系。 http://en.wikipedia.org/wiki/Junction_table http://en.wikipedia.org/wiki/Junction_table

If database table name will booking and column Like如果数据库表名将预订和列 Like

id room_ids id room_ids

1 2, 4, 5 1 2、4、5

2 4, 3 2 4, 3

SELECT SUM(LENGTH(room_id) - LENGTH(REPLACE(room_id, ',', '')) + 1) as total FROM booking

Click here for Demo 点击这里进行演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM