[英]Other function like FIND_IN_SET which returns number of strings available in comma separated list
As per official documentation, FIND_IN_SET returns the position of the first occurrence of string available from a comma-separated list. 根据官方文档,FIND_IN_SET返回逗号分隔的列表中首次出现的字符串的位置。 But I want to get the count of available string in a comma-separated list.
但是我想获取逗号分隔列表中可用字符串的数量。
For example : 例如 :
SELECT id, name, FIND_IN_SET(id, '1,1,2,3,4,4,5,6,7,7,7') as num FROM users;
It returns the following result 它返回以下结果
+----+---------------+
| 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 Fiddle: http://sqlfiddle.com/#!9/9eeacb/2 SQL小提琴: http ://sqlfiddle.com/#!9 / 9eeacb / 2
But I want the count of ids which matches the id of the table. 但是我想要与表的ID相匹配的ID数量。 So, the expected output should be like below.
因此,预期输出应如下所示。
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 |
+----+---------------+
The best answer is to move away from the CSV paradigm, and instead get the set of id
s to match into its own table: 最好的答案是远离CSV范式,而是获取一组
id
匹配到自己的表中:
CREATE TABLE ids (id int);
INSERT INTO ids (id)
VALUES (1),(1),(2),(3),(4),(4),(5),(6),(7),(7),(7);
Then use the following simple query: 然后使用以下简单查询:
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;
Use string functions tricks: 使用字符串函数的技巧:
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
See the demo (with other possible cases). 参见演示 (其他可能的情况)。
Results: 结果:
id | name | num
1 | Jack | 2
2 | Alex | 1
3 | John | 1
4 | Brett | 2
5 | Keith | 1
6 | Richard | 1
7 | Kent | 3
You are passing in the comparison values as a string. 您将比较值作为字符串传递。 You can do some string tricks to count the number of values within the string and then add that up:
您可以使用一些字符串技巧来计算字符串中值的数量,然后将其累加:
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;
Note: I created the subquery x
as a convenience, so I can refer to ids
. 注意:为了方便起见,我创建了子查询
x
,因此可以引用ids
。 You can pass in the value as a parameter instead: 您可以将值作为参数传递:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.