每個人都應該有一個好的分離器。有很多選項可用。然而,我確實提供了我使用的那個。
下面列出兩個選項,第一個是內嵌版本,第二個使用解析函數。兩者都會返回相同的結果。
選項1 - 如果沒有一個解析函數
Declare @MonthNoCsv varchar(50) = '2,3,4'
;with cte as (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@MonthNoCsv,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
)
Select U.*
from cte M
Join Bookings B on M.RetVal=B.MonthNo and B.IsPaid=1
Join Users U on U.UserID=B.UserID
Group By U.UserID,U.Name
Having Count(Distinct B.MonthNo)=(Select max(RetSeq) from cte)
選項2 - 對於parse函數
Declare @MonthNoCsv varchar(50) = '2,3,4'
;with cte as (
Select * from [dbo].[udf-Str-Parse](@MonthNoCsv,',')
)
Select U.*
from cte M
Join Bookings B on M.RetVal=B.MonthNo and B.IsPaid=1
Join Users U on U.UserID=B.UserID
Group By U.UserID,U.Name
Having Count(Distinct B.MonthNo)=(Select max(RetSeq) from cte)
都返回
UserID Name
2 Bill
的UDF如果有興趣
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')
此鏈接http://www.sommarskog.se/arrays-in-sql-2008.html可能讓你開始 - 但我懷疑它需要技巧的水平超出了你的實施能力。在http://www.sommarskog.se/arrays-in-sql.html – SMor