如何将表中列中的逗号分隔值放入 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 运算符?的主要内容,如果未能解决你的问题,请参考以下文章