其中IN以逗号分隔的字符串

时间:2015-05-28 16:52:00

标签: sql-server delimiter where-in

我想从临时表#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)?

3 个答案:

答案 0 :(得分:9)

创建一些拆分字符串函数并将逗号分隔值转换为行,然后可以使用转换后的行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' s 答案)。

另一种方法是使用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。

答案 1 :(得分:4)

因为变量有一个字符串,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))

答案 2 :(得分:1)

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

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