如何将表中列中的逗号分隔值放入 SQL IN 运算符?

Posted

技术标签:

【中文标题】如何将表中列中的逗号分隔值放入 SQL IN 运算符?【英文标题】:How to put a comma separated value from a column in a table into SQL IN operator? 【发布时间】: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 中引入的。 我在其中存储了一个逗号分隔的文本,每个逗号分隔值都带有单引号。不。每行存储一项。 【参考方案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

【讨论】:

以上是关于如何将表中列中的逗号分隔值放入 SQL IN 运算符?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据列中的逗号分隔值进行选择

如何将表数据连接到一个逗号分隔的列中[重复]

用其他表中列的唯一值数填充sql表中的列

SQL:将行与列中的逗号分隔值合并

在SQL过程中将一列中的逗号分隔值拆分为多列

Oracle SQL:为列中的每个值创建一个新行,其中更多值用逗号分隔