【问题标题】:How can I check whether a number is contained in comma separated list stored in a varchar column?如何检查数字是否包含在存储在 varchar 列中的逗号分隔列表中?
【发布时间】:2022-04-19 19:31:58
【问题描述】:

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

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

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

select * 
from myTable 
where 3 in (categoryIds)

我知道通过this 在 MySQL 中可以做到这一点,但在 SQL Server 中也可以做到吗?

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

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

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

【问题讨论】:

  • 您应该考虑一下您的数据库设计。以 csv 格式存储值不是一个好习惯。
  • 不要将数据存储为解决方案中的逗号分隔值。每行一个值是 SQL 方式!
  • 可能是这样的:SELECT * FROM myTable WHERE ',' + categoryId + ',' LIKE '%,3,%';
  • 感谢您的意见,我们最终改用“SQL 方式” :)
  • 对您的表格进行标准化非常好!存储 csv 列表会使 一切 变得更加困难......正如这个问题所证明的那样。

标签: sql sql-server


【解决方案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

【讨论】:

  • 如果我要搜索 id=2(two),那么它会检索到 12、20、21 等。对吗?
  • @NaveenNikhil 实际上不,它只会查找特定的完整数字,这就是为什么这里有 4 个不同的 WHERE 子句。
  • 但是这些子句是用 OR 组合的。你能确认一下吗?
  • 是的,它们是结合在一起的。你要我确认什么?我知道这行得通。
  • @GauravAggarwal 是的,你可以使用 inset,但这个问题是 SQL Server,而不是 MySQL
【解决方案2】:
SELECT * 
FROM myTable 
WHERE (',' + RTRIM(categoryIds) + ',') LIKE '%,' + @stringId + ',%'

这里的@stringId 是您要搜索的文本。这样可以避免不必要的多个where条件

亲切的问候, 拉古.M.

【讨论】:

    【解决方案3】:

    因为它还没有被提及,所以可以使用 STRING_SPLIT([values], ',') 来实现所需的检查。该功能自 SQL Server 2016 起可用。由于问题的年代久远,我假设未满足此先决条件,即提出问题的时间。

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

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

    【讨论】:

      【解决方案4】:

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

      DECLARE @categoryId INT
      SET @categoryId = 3
      
      SELECT *
      FROM myTable
      WHERE CHARINDEX(',' + CAST(@categoryId AS VARCHAR(MAX)) + ',', ',' + categoryIds + ',') > 0
      

      【讨论】:

        【解决方案5】:

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

        DECLARE     @categoryIds    nvarchar(50) = '1, 2, 3, 4, 5'
        
        EXEC        ('SELECT      *
                      FROM        myTable
                      WHERE       categoryId IN (' + @categoryIds + ')')
        

        【讨论】:

          【解决方案6】:
          SELECT *
          FROM user_master
          WHERE user_tags REGEXP '[[:<:]]10[[:>:]]'
             OR user_tags REGEXP '[[:<:]]11[[:>:]]'  
          

          【讨论】:

            【解决方案7】:

            使用FIND_IN_SET()mysql函数

            语法

            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");
            

            【讨论】:

            • 这个问题不是针对 MySQL,FIND_IN_SET 在 SQL Server 中不可用。
            猜你喜欢
            • 2022-06-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多