【问题标题】:How to put a comma separated value from a column in a table into SQL IN operator?如何将表中列中的逗号分隔值放入 SQL IN 运算符?
【发布时间】:2019-12-30 06:02:51
【问题描述】:

我有一个表,其中有一列我存储一个逗号分隔的文本,每个逗号分隔的值都带有单引号。这些值是员工 ID。看起来是这样的

现在,我有一个 SQL 查询,我需要将此列中的值放入 SQL IN 运算符中。像这样的:

select * 
from EMPLOYEE_MASTER 
where EMPLOYEEID IN (select CM_CONFIG_VALUE 
                     from ADL_CONFIG_MAST_T 
                     where CM_CONFIG_KEY like 'ATT_BIOMETRIC_OU_ID'
                    )

但这不起作用,执行时的查询返回 0 行,而如果我像下面这样正常执行查询,它可以工作。

select * 
from EMPLOYEE_MASTER 
where EMPLOYEEID IN('9F3DD4B791554DDE','C9B90D62851D43AB','828CB9E6204B4DDC')

请建议我应该在这里做什么。我曾尝试使用子字符串删除第一个和最后一个字符,并假设单引号可能是问题,但这也不起作用。

【问题讨论】:

  • 您使用的是什么SQL Server 版本?
  • @YogeshSharma SQL Server 2014
  • 您可以使用STRING_SPLIT函数docs.microsoft.com/en-us/sql/t-sql/functions/…。但我认为它是在 SQL Server 2015 中引入的。
  • 我在其中存储了一个逗号分隔的文本,每个逗号分隔值都带有单引号。不。每行存储一项。

标签: sql sql-server sql-server-2014


【解决方案1】:
select * from EMPLOYEE_MASTER where EMPLOYEEID IN(select EMPLOYEEID from ADL_CONFIG_MAST_T where CM_CONFIG_KEY like 'ATT_BIOMETRIC_OU_ID')

columnname 所在的列应该相同(从表名中选择 COLUMNMNAE)

【讨论】:

  • 我在 where 子句中使用列名 CM_CONFIG_VALUE 的原因是,CM_CONFIG_VALUE 应该存储以逗号分隔的员工 ID 列表,我的要求是我需要根据该列中的员工 ID。表 ADL_CONFIG_MAST_T 中不存在 EMPLOYEEID 列。
  • 好的。那么在这种情况下使用 join 。在这种情况下查询将不起作用
【解决方案2】:

您可以创建一个临时变量,然后使用exec 命令获得所需的结果。

declare @temp varchar(200)
select @temp=CM_CONFIG_VALUE 
                from ADL_CONFIG_MAST_T 
                     where CM_CONFIG_KEY like 'ATT_BIOMETRIC_OU_ID'

exec('select * 
from EMPLOYEE_MASTER 
where EMPLOYEEID IN (' + @temp + ')')

【讨论】:

  • 我已经在临时表上测试过它并且工作正常。
【解决方案3】:

试试这个:

DECLARE @ID VARCHAR(500);
DECLARE @Number VARCHAR(500);
DECLARE @comma CHAR;

SET @comma = ','
SET @ID = (select CM_CONFIG_VALUE 
                     from ADL_CONFIG_MAST_T 
                     where CM_CONFIG_KEY like %ATT_BIOMETRIC_OU_ID% + @comma);

Create table #temp (EMPLOYEEID varchar(500))
WHILE CHARINDEX(@comma, @ID) > 0
BEGIN
    SET @Number = SUBSTRING(@ID, 0, CHARINDEX(@comma, @ID))
    SET @ID = SUBSTRING(@ID, CHARINDEX(@comma, @ID) + 1, LEN(@ID))

    Insert into #temp
    select @Number

END
select * 
from EMPLOYEE_MASTER 
where EMPLOYEEID IN(select EMPLOYEEID from #temp)

【讨论】:

  • 使用这种方法,最后创建的查询是 select * from EMPLOYEE_MASTER where EMPLOYEE_ID IN(select CM_CONFIG_VALUE wfrom ADL_CONFIG_MAST_T where CM_CONFIG_KEY like 'ATT_BIOMETRIC_OU_ID%'),这又返回 0 行。跨度>
  • 您遇到了什么问题?
【解决方案4】:

您没有在查询中得到它的原因是您的内部查询只返回一行。因此,您的查询将 '9F3DD4B791554DDE','C9B90D62851D43AB','828CB9E6204B4DDC' 作为单个记录进行搜索。

如果您的compatibility level 大于或等于130,您可以使用STRING_SPLIT() 函数。那么您的查询将是

SELECT *
FROM EMPLOYEE_MASTER
WHERE EMPLOYEEID IN 
    (SELECT value AS empid
    FROM ADL_CONFIG_MAST_T CROSS APPLY string_split(CM_CONFIG_VALUE, ',' )
    WHERE CM_CONFIG_KEY LIKE 'ATT_BIOMETRIC_OU_ID' )

这实际上做的是,它将 CM_CONFIG_VALUE 与 ',' 分开,并将它们作为行返回。这是我提到的价值列。然后将它们与 IN 子句一起使用。

希望这会有所帮助!

【讨论】:

    【解决方案5】:

    直接IN 条件在这里不起作用。您在搜索之前已拆分字符串。您可以使用SQL SERVER 2014 中的XML 选项来做到这一点

    SELECT *
    FROM EMP
    WHERE EMPID IN (
          SELECT a.c.value('.', 'VARCHAR(1000)')
               FROM (
                     SELECT x = CAST('<a>' + 
                     REPLACE(REPLACE(CM_CONFIG_VALUE , ',', '</a><a>'),'''','') + '</a>' AS XML  ) 
                     FROM ADL_CONFIG_MAST_T
                   -- WHERE <your_condition>
                    ) m
          CROSS APPLY x.nodes('/a') a(c))
    

    CHECK DEMO HERE

    对于 2016 及更高版本,您可以使用兼容级别 130 的STRING_SPLIT

    【讨论】:

      猜你喜欢
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 2011-05-09
      • 1970-01-01
      • 2014-11-07
      相关资源
      最近更新 更多