具有分析/拆分功能和交叉应用。
我应该补充一点,如果你不能使用或不想使用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类型字段来存储多个值(查询速度会很慢)。如果“字母”本身就是实体,那么您应该为它们使用一个表格,另一个将它们与“数字”联系起来 –