在逗号分隔的字符串中[重复]

Posted

技术标签:

【中文标题】在逗号分隔的字符串中[重复]【英文标题】:Where IN a Comma delimited string [duplicate] 【发布时间】:2015-08-11 07:41:42 【问题描述】:

我想从临时表#temptable 的完整列表中检索某些用户。 查询如下所示:

DECLARE @List varchar(max)
SELECT @List = coalesce(@List + ',','') + '''' + StaffCode + ''''
FROM tblStaffs

SELECT UserName
FROM #temptable
WHERE #temptable.StaffCode IN (@List)

我可以看出@List 的格式正确:

'AAA','ABB','BBB','CCC','DDD','MMM'

如果我把它改成

WHERE #temptable.StaffCode IN ('AAA','ABB','BBB','CCC','DDD','MMM')

它确实有效,那为什么不 IN (@List)?

【问题讨论】:

它不适用于in ('''AAA'',''BBB'''),这确实是正在发生的事情;我相信您需要将 @List 解析为一个小临时表并加入它。 感谢您指出这一点。这真的是我想知道的。解决此问题的一种方法是使用 Eric 从上一个问题中回答的动态 sql:***.com/questions/878833/… 【参考方案1】:

创建一些拆分字符串函数并将逗号分隔的值转换为行,然后您可以使用转换后的行IN 子句

DECLARE @List VARCHAR(max)

SELECT @List = COALESCE(@List + ',', '') +StaffCode
FROM   tblStaffs

SELECT UserName
FROM   #temptable
WHERE  #temptable.StaffCode IN (SELECT split_values
                                FROM   dbo.Splitstring_function(@list)) 

检查here 的各种拆分字符串功能

如果您不想创建函数,那么您也可以直接使用代码而不是创建新函数(M.Ali 的答案)。

另一种方法是使用dynamic query

Declare @List varchar(max), @sql nvarchar(max)

Select @List = coalesce(@List + ',','') + '''' + StaffCode + ''''
From tblStaffs

set @sql = '
Select UserName
From #temptable
Where #temptable.StaffCode IN ('+ @List + ')'

--print @sql
exec (@sql)

要调试动态查询,在执行前总是print动态sql。

【讨论】:

@Zerubbabel - 它只是一个示例,您需要创建一个拆分字符串函数。我也给了你一个链接,你可以从那里创建一个拆分字符串函数。 @Zerubbabel - 更新了另一个答案,看看吧。【参考方案2】:

因为变量有一个字符串,IN 运算符读取为'AAA'',''ABB'',''BBB',并将其视为单个值。

在您的查询中,您应该真正在 IN 运算符中使用查询本身,例如......

Select UserName
From #temptable
Where #temptable.StaffCode IN (SELECT StaffCode From tblStaffs)

无论如何,如果需要使用变量,然后从该变量中读取 IN 运算符中的值,您可以执行以下操作....

DECLARE @List VARCHAR(1000);

Select @List = coalesce(@List + ',','') + StaffCode 
From tblStaffs


SELECT *
From #temptable
Where #temptable.StaffCode IN (
     SELECT t.c.value('.', 'VARCHAR(1000)')
           FROM (
                 SELECT x = CAST('<t>' + 
                  REPLACE(@List , ',', '</t><t>') + '</t>' AS XML)
                ) a
     CROSS APPLY x.nodes('/t') t(c))

【讨论】:

【参考方案3】:

我建议您根本不要使用逗号分隔的字符串。请考虑使用semi-join:

select [Temp].[UserName] 
from 
    #temptable [Temp]
where
    exists (select 1 from [tblStaffs] where [tblStaffs].[StaffCode] = [Temp].[StaffCode]); 

【讨论】:

如果@List 是存储过程或函数参数怎么办? @GlassCannon 我只提出这个建议是因为 OP 中的示例没有 @List 作为 sproc 参数,而是在使用它之前立即声明和填充的东西。如果它 sproc 参数,并且如果允许更改sproc 的签名,那么我建议使用表值参数而不是逗号分隔的字符串。如果由于某种原因无法修改 sproc 的参数,那么(并且只有这样)我会考虑接受的答案中描述的字符串拆分函数。

以上是关于在逗号分隔的字符串中[重复]的主要内容,如果未能解决你的问题,请参考以下文章

用PHP检查逗号分隔的字符串中是不是存在值[重复]

在c#中拆分逗号分隔多个字符串[重复]

在postgresql中将值提取到逗号分隔的字符串中[重复]

从逗号分隔的字符串中删除重复项 (Amazon Redshift)

将字符串中的逗号分隔数字转换为数字向量[重复]

将逗号分隔的字符串转换为数组[重复]