具有分析/拆分功能和交叉應用。
我應該補充一點,如果你不能使用或不想使用UDF,那麼解析可以很容易地移植到CROSS APPLY中。
Declare @YourTable table (Col1 varchar(25),Col2 int)
Insert Into @YourTable Values
('A', 1),
('B,C', 1),
('B,C', 2),
('A,C', 1),
('A,C', 2),
('B,A,D', 1),
('B,A,D', 2),
('B,A,D', 3)
Select A.*
,Col3 = B.RetVal
From @YourTable A
Cross Apply (Select * from [dbo].[udf-Str-Parse](A.Col1,',') where RetSeq=A.Col2) B
返回
Col1 Col2 Col3
A 1 A
B,C 1 B
B,C 2 C
A,C 1 A
A,C 2 C
B,A,D 1 B
B,A,D 2 A
B,A,D 3 D
的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(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
只是爲了好玩,這是NON-UDF版本
Select A.*
,Col3 = B.RetVal
From @YourTable A
Cross Apply (
Select * From(
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(A.Col1,',','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) C where RetSeq=A.Col2
) B
您使用的是哪個版本的SQL Server? – squillman
存儲逗號分隔的字符串,而不是使用字段和關係是一個非常嚴重的設計錯誤。你需要修復這個bug,而不是尋找掩蓋它的方法。您可以使用'STRING_SPLIT'方法作爲快速修復方法,直到您修復根目錄錯誤。 –
什麼是「A,B,C」值?這張桌子的目的是什麼?有多種方法可以修復此設計。選擇正確的取決於你想要對他們做什麼。您可以使用稀疏列,即每個字母有一列,而不會浪費額外空間。您可以使用XML或JSON類型字段來存儲多個值(查詢速度會很慢)。如果「字母」本身就是實體,那麼您應該爲它們使用一個表格,另一個將它們與「數字」聯繫起來 –