SQL:如何动态创建列

时间:2017-04-24 16:48:03

标签: sql sql-server tsql pivot

我有一个动态创建的表。因此,在创建时列数是未知的。我想在同一个表中创建每列的副本,第一列包含逗号分隔值的第一部分,第二列包含第二部分,依此类推

例如,

  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

我无法为可变数量的列

实现此目的

1 个答案:

答案 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);

<强>返回

enter image description here