其他函数,例如FIND_IN_SET,它返回逗号分隔列表中可用的字符串数

时间:2019-08-28 04:59:09

标签: mysql sql

根据官方文档,FIND_IN_SET返回逗号分隔的列表中首次出现的字符串的位置。但是我想获取逗号分隔列表中可用字符串的数量。

例如:

SELECT id, name, FIND_IN_SET(id, '1,1,2,3,4,4,5,6,7,7,7') as num FROM users;

它返回以下结果

+----+---------------+
| id | name    | num |
+----+---------------+
|  1 | Jack    |   1 |
|  2 | Alex    |   3 |
|  3 | John    |   4 |
|  4 | Brett   |   5 |
|  5 | Keith   |   7 |
|  6 | Richard |   8 |
|  7 | Kent    |   9 |
+----+---------------+

SQL小提琴:http://sqlfiddle.com/#!9/9eeacb/2

但是我想要与表的ID相匹配的ID数。因此,预期输出应如下所示。

SELECT id, name, SOME_FUNCTION(id, '1,1,2,3,4,4,5,6,7,7,7') as num FROM users;

    +----+---------------+
    | id | name    | num |
    +----+---------------+
    |  1 | Jack    |   2 |
    |  2 | Alex    |   1 |
    |  3 | John    |   1 |
    |  4 | Brett   |   2 |
    |  5 | Keith   |   1 |
    |  6 | Richard |   1 |
    |  7 | Kent    |   3 |
    +----+---------------+

3 个答案:

答案 0 :(得分:1)

最好的答案是远离CSV范式,而是获取id的集合以匹配到其自己的表中:

CREATE TABLE ids (id int);
INSERT INTO ids (id)
VALUES (1),(1),(2),(3),(4),(4),(5),(6),(7),(7),(7);

然后使用以下简单查询:

SELECT
    u.id,
    u.name,
    COUNT(i.id) AS num
FROM users u
LEFT JOIN ids i
    ON u.id = i.id
GROUP BY
    u.id,
    u.name;

答案 1 :(得分:1)

使用字符串函数的技巧:

set @s = '1,1,2,3,4,4,5,6,7,7,7';
select id, name,
  ceiling((length(@s) - length(trim(both ',' from replace(
    replace(concat(',', replace(@s, ',', ',,'), ','), concat(',', id, ',' ), ''),
    ',,', ','
  )))) / (length(id) + 1)) as num
from users

请参阅demo(以及其他可能的情况)。
结果:

id | name    | num
 1 | Jack    | 2
 2 | Alex    | 1
 3 | John    | 1
 4 | Brett   | 2
 5 | Keith   | 1
 6 | Richard | 1
 7 | Kent    | 3

答案 2 :(得分:0)

您将比较值作为字符串传递。您可以使用一些字符串技巧来计算字符串中值的数量,然后将其累加:

SELECT u.id, u.name,
       COUNT(*),
       SUM( (LENGTH(REPLACE(CONCAT(',', ids, ','), u.id, CONCAT(u.id, 'X'))) -
             LENGTH(CONCAT(',', ids, ','))
            ) 
          )
FROM users u CROSS JOIN
     (SELECT '1,1,2,3,4,4,5,6,7,7,7' as ids) x
WHERE FIND_IN_SET(u.id, x.ids) > 0
GROUP BY u.id, u.name;

注意:为方便起见,我创建了子查询x,因此可以引用ids。您可以改为将值作为参数传递:

SELECT u.id, u.name,
       COUNT(*),
       SUM( (LENGTH(REPLACE(CONCAT(',', ?, ','), u.id, CONCAT(u.id, 'X'))) -
             LENGTH(CONCAT(',', ?, ','))
            ) 
          )
FROM users u 
WHERE FIND_IN_SET(u.id, ?) > 0
GROUP BY u.id, u.name;