我有一个动态创建的表。因此,在创建时列数是未知的。我想在同一个表中创建每列的副本,第一列包含逗号分隔值的第一部分,第二列包含第二部分,依此类推
例如,
ID Value1 Value2 .... Valuen
1 1;2;3 4;5;6
2 A;B;C D;E;F
我想得到像
这样的输出 ID Value1Copy1 Value1Copy2 Value1Copy3 Value2Copy1 Value2Copy2 Value2Copy3 .... ValuenCopy1
1 1 2 3 4 5 6
2 A B C D E F
我无法为可变数量的列
实现此目的答案 0 :(得分:1)
以下内容将动态取消您的数据。 您可能会注意到指定的唯一字段是ID 。
结果将被放入#Temp
表中。从那里我们执行动态支点
示例强>
Declare @YourTable table (ID int,Value1 varchar(50),Value2 varchar(50))
Insert Into @YourTable values
( 1, '1;2;3','4;5;6'),
( 2, 'A;B;C','D;E;F')
Select A.ID
,Col = concat(C.Item,'Copy',D.RetSeq)
,Value = D.RetVal
Into #Temp
From @YourTable A --<< Replace with Your actual table
Cross Apply (Select XMLData = cast((Select A.* For XML Raw) as xml ) ) B
Cross Apply (
Select Item = attr.value('local-name(.)','varchar(100)')
,Value = attr.value('.','varchar(max)')
From B.XMLData.nodes('/row') as A(r)
Cross Apply A.r.nodes('./@*') AS B(attr)
Where attr.value('local-name(.)','varchar(100)') not in ('ID','Other2Exclude')
) C
Cross Apply (
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(C.Value,';','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) D
Where A.ID is not null -- or any other WHERE statement
Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(Col) From #Temp Order by 1 For XML Path('')),1,1,'')
Select @SQL = '
Select *
From #Temp
Pivot (max(Value) For [Col] in (' + @SQL + ') ) p'
Exec(@SQL);
<强>返回强>