如何检查存储在 varchar 列中的逗号分隔列表中是否包含数字?

How can I check whether a number is contained in comma separated list stored in a varchar column?

提问人:Schileru 提问时间:10/22/2015 最后编辑:CommunitySchileru 更新时间:2/16/2023 访问量:40499

问:

我有一个带有列的表。它包含一些用逗号分隔的 ID,例如:varcharcategoryIds

id       categoryIds
-------------------- 
1        3,7,12,33,43

我想做一个 select 语句并检查该列中是否存在 int。像这样的东西:

select * 
from myTable 
where 3 in (categoryIds)

我知道这样做可以在MySQL中实现,但是在SQL Server中也可以完成吗?

我尝试将 int 转换为运行以下语句的 char:

select * 
from myTable 
where '3' in (categoryIds)

但看起来对逗号分隔列表没有任何“开箱即用”的支持,因为它不返回任何内容。

sql-server

评论

5赞 Jens 10/22/2015
您应该考虑您的数据库设计。以 csv 格式存储值不是一个好的做法。
3赞 jarlh 10/22/2015
不要在解决方案中将数据存储为逗号分隔的值。每行一个值是 SQL 方式!
2赞 dwjv 10/22/2015
可能是这样的:SELECT * FROM myTable WHERE ',' + categoryId + ',' LIKE '%,3,%';
0赞 Schileru 10/23/2015
感谢您的输入,我们最终以“SQL 方式”代替了:)
0赞 SOS 2/19/2022
对你的正常化表有好处!存储 csv 列表使一切变得更加困难......正如这个问题所证明的那样。

答:

20赞 DavidG 10/22/2015 #1

您确实应该重新设计此表,以将这些值从逗号分隔拆分为在单独的行中。但是,如果这是不可能的,则只能进行字符串比较:

DECLARE @id INT = 3
DECLARE @stringId VARCHAR(50) = CAST(@id AS VARCHAR(50))

SELECT * 
FROM MyTable 
WHERE categoryIds = @stringId -- When there is only 1 id in the table
OR categoryIds LIKE @stringId + ',%' -- When the id is the first one
OR categoryIds LIKE '%,' + @stringId + ',%' -- When the id is in the middle
OR categoryIds LIKE '%,' + @stringId -- When the id is at the end
0赞 Peter Elzinga 10/22/2015 #2

您可以像这样使用动态 SQL:

DECLARE     @categoryIds    nvarchar(50) = '1, 2, 3, 4, 5'

EXEC        ('SELECT      *
              FROM        myTable
              WHERE       categoryId IN (' + @categoryIds + ')')
2赞 MikeBeaton 9/19/2016 #3

不确定这是否会比 DavidG 的建议更快或更慢,但为了仅通过一次检查获得相同的匹配项,您可以执行以下操作:

DECLARE @categoryId INT
SET @categoryId = 3

SELECT *
FROM myTable
WHERE CHARINDEX(',' + CAST(@categoryId AS VARCHAR(MAX)) + ',', ',' + categoryIds + ',') > 0
-6赞 Sujal Patel 12/27/2016 #4

使用MySQL函数FIND_IN_SET()

语法

SELECT * FROM <table name> as a WHERE FIND_IN_SET(value to search in string,comma separated string);

SELECT * FROM <table name> as a WHERE FIND_IN_SET(5,"1,2,3,4,5,6");

评论

6赞 Derrick Moeller 12/27/2016
此问题不是针对 MySQL,FIND_IN_SET SQL Server 中不可用。
9赞 Raghurocks 5/16/2017 #5
SELECT * 
FROM myTable 
WHERE (',' + RTRIM(categoryIds) + ',') LIKE '%,' + @stringId + ',%'

这里@stringId是要搜索的文本。通过这种方式,您可以避免不必要的多重 where 条件

亲切问候 拉古

0赞 Chirag Pipariya 3/16/2018 #6
SELECT *
FROM user_master
WHERE user_tags REGEXP '[[:<:]]10[[:>:]]'
   OR user_tags REGEXP '[[:<:]]11[[:>:]]'  
7赞 Dominik Klug 4/30/2021 #7

由于尚未提及,因此可以使用 STRING_SPLIT([values], ',') 来实现所需的检查。该函数自 SQL Server 2016 起可用。由于问题的年代久远,我认为这个条件没有得到满足,它被问到的时间。

select [id], [categoryIds] 
from [myTable] 
where '3' in (select value from STRING_SPLIT([categoryIds], ','))

这应该优于上述基于字符串的比较。