如何使用逗号分隔符将行中的多个值转换为多个列?

时间:2017-07-16 09:08:20

标签: sql sql-server tsql

如何将行中的多个逗号分隔值转换为SQL Server中的多个列,就像我有一个包含两行的表一样

A1,1,B1,2 
C1,3,D4,4  

我想要这样的输出

col1 col2 col3 col4
 A1   1     B1   2
 C1   3     D4   4

2 个答案:

答案 0 :(得分:1)

如果您有有限或最大列数

,则另一个选项

示例

Declare @YourTable Table ([YourCol] varchar(50))
Insert Into @YourTable Values 
 ('A1,1,B1,2')
,('C1,3,D4,4')

Select B.*
 From @YourTable A
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(A.YourCol,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as x
             ) B

<强>返回

Pos1    Pos2    Pos3    Pos4    Pos5    Pos6
A1      1       B1      2       NULL    NULL
C1      3       D4      4       NULL    NULL
  

编辑 - 只是为了好玩,这是以上的动态版

只需将YourTable替换为您的实际表名,并将YourCol替换为要拆分的所需列。

Declare @SQL nvarchar(max)
Set @SQL = Stuff((Select concat(',Col',N,' = ltrim(rtrim(xDim.value(''/x[',N,']'',''varchar(max)'')))') 
                   From  (
                           Select Top ((Select max(len(YourCol)-len(replace(YourCol,',','')))+1 From YourTable)) 
                                  N=Row_Number() Over (Order By (Select NULL)) 
                            From  master..spt_values
                          ) A 
                    For XML Path ('')),1,1,'')
Set @SQL = '
Select A.*,B.*
 From  YourTable A
 Cross Apply ( Select ' + @SQL +' From  (Select Cast(''<x>'' + replace((Select replace(A.YourCol,'','',''§§Split§§'') as [*] For XML Path('''')),''§§Split§§'',''</x><x>'')+''</x>'' as xml) as xDim ) x ) B
'
--Print @SQL
Exec(@SQL)

<强>返回

YourCol     Col1    Col2    Col3    Col4
A1,1,B1,2   A1      1       B1      2
C1,3,D4,4   C1      3       D4      4

答案 1 :(得分:0)

假设您的表名为t,您可以按照以下步骤进行操作

第1步:使用CSV tally type splitter

拆分列

第2步: PIVOT输出值

在单个查询中,解决方案将是

select * from 
(
select 
    t.col as col,
    row_number() over (partition by t.col order by t1.N asc) as row_num,
    SUBSTRING( t.col, t1.N, ISNULL(NULLIF(CHARINDEX(',',t.col,t1.N),0)-t1.N,4000)) as split_values
from t 
    join
    (
        select 
            t.col,
            1 as N 
        from t  
            UNION ALL
        select 
            t.col,
            t1.N + 1 as N
        from t 
            join
            (
             select 
                top 4000
                    row_number() over(order by (select NULL)) as N 
             from 
                sys.objects s1 
                    cross join 
               sys.objects s2 
            ) t1 
        on SUBSTRING(t.col,t1.N,1) = ','
     ) t1
     on t1.col=t.col
)src
PIVOT
( max(split_values) for row_num in ([1],[2],[3],[4],[5],[6],[7],[8]))p

working demo

PS:如果你不知道列中的最大逗号,你实际上可以使用动态数据透视。