将逗号分隔值放入单独或不同的列中

时间:2021-10-13 21:21:28

I have a table and values as shown here

我有一个表和值,如下所示

create table #example(id int primary key identity, cols varchar(255))
insert into #example(cols) values('HI,HELLO,BYE,TC')
insert into #example(cols) values('WHAT,ARE,YOU,DOING,HERE')

I need the resultant output as shown in the picture

我需要结果输出,如图所示

Note : There is no limit for values i.e dynamic

注意:动态值没有限制

将逗号分隔值放入单独或不同的列中

3 个解决方案

#1


5  

This is what you are expecting

这是你所期待的

Schema:

架构:

CREATE TABLE #EXAMPLE(ID INT PRIMARY KEY IDENTITY, COLS VARCHAR(255))
INSERT INTO #EXAMPLE(COLS) VALUES('HI,HELLO,BYE,TC')
INSERT INTO #EXAMPLE(COLS) VALUES('WHAT,ARE,YOU,DOING,HERE')

Do split those comma separated values into Rows and Apply pivot

将这些逗号分隔值拆分为Rows和Apply pivot

SELECT * FROM (
SELECT id
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2
, SPLT.CLMS.value('.','VARCHAR(MAX)') AS LIST FROM ( 
select id
, CAST( '<M>'+REPLACE(cols,',','</M><M>')+'</M>' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes('/M') AS SPLT(CLMS)
)A
PIVOT
(
    MAX(LIST) FOR ID2 IN ([1],[2],[3],[4],[5])
)PV

You will get result as

你会得到结果

+----+------+-------+-----+-------+------+
| id |  1   |   2   |  3  |   4   |  5   |
+----+------+-------+-----+-------+------+
|  1 | HI   | HELLO | BYE | TC    | NULL |
|  2 | WHAT | ARE   | YOU | DOING | HERE |
+----+------+-------+-----+-------+------+

Edit:

编辑:

And now you need to go for dynamic pivot,since There is no limit for values.

现在你需要进行动态调整,因为值没有限制。

DECLARE @COLS VARCHAR(MAX)='', @QRY VARCHAR(MAX)='';


SELECT @COLS =@COLS+'['+CAST( ID2 AS VARCHAR(10))+'],' FROM (
SELECT  DISTINCT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2  FROM ( 
select id, CAST( '<M>'+REPLACE(cols,',','</M><M>')+'</M>' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes('/M') AS SPLT(CLMS)
)A

SELECT @COLS = LEFT(@COLS,LEN(@COLS)-1)


SELECT @QRY =
'
SELECT * FROM (
SELECT id
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2
, SPLT.CLMS.value(''.'',''VARCHAR(MAX)'') AS LIST FROM ( 
select id, CAST( ''<M>''+REPLACE(cols,'','',''</M><M>'')+''</M>'' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes(''/M'') AS SPLT(CLMS)
)A
PIVOT
(
    MAX(LIST) FOR ID2 IN ('+@COLS+ ')
)PV'

EXEC( @QRY)

#2


1  

Dynamic version base on split string then pivot table

基于拆分字符串然后数据透视表的动态版本

Schema:

架构:

create table #example(id int primary key identity, cols varchar(255))
insert into #example(cols) values('HI,HELLO,BYE,TC')
insert into #example(cols) values('WHAT,ARE,YOU,DOING,HERE')

Calculate columns pivot

计算列枢轴

-- Calculate dynamic columns
;WITH temps AS 
(
  SELECT sd.* ,CAST('<x>' + replace(sd.cols, ',', '</x><x>') + '</x>' as xml) AS xmlText
  FROM #example sd
),
temps1 AS
(
   SELECT t.Id, t.cols, v.x.value('.','varchar(50)') AS Value
   FROM temps t
   CROSS APPLY 
     t.xmlText.nodes('/x') AS v(x)
)
SELECT @ColumnPivot =  STUFF((SELECT DISTINCT CONCAT(',COL',row_number() OVER(PARTITION BY t.id ORDER BY t.Value)) FROM temps1 t FOR XML PATH('')), 1,1,'')

PRINT @ColumnPivot

Then PIVOT table

然后是PIVOT表

 DECLARE @query nvarchar(max) = 
   CONCAT(N';WITH temps AS 
   (
      SELECT sd.* ,CAST(''<x>'' + replace(sd.cols, '','', ''</x><x>'') + ''</x>'' as xml) AS xmlText
      FROM #example sd
   ),
   temps1 AS
   (
      SELECT t.Id, t.cols, v.x.value(''.'' , ''varchar(50)'') AS Value
      FROM temps t
      CROSS APPLY 
         t.xmlText.nodes(''/x'') AS v(x)
   ),
   temps2 AS
   (
      SELECT t.* , CONCAT(''COL'',row_number() OVER(PARTITION BY t.id ORDER BY (select 1))) AS ColGroup
      FROM temps1 t
   )',
    N'SELECT Id, cols, ' , @ColumnPiVot,
  ' FROM
    (
       select * from temps2
    ) AS src
  PIVOT 
    (MAX(Value) FOR ColGroup IN (',@ColumnPiVot,')) AS pvt')
  PRINT @query
  exec sp_executesql  @query

DROP TABLE #example

Demo link: Rextester

演示链接:Rextester

#3


0  

          DECLARE @COLS AS NVARCHAR(MAX),
    @QUERY  AS NVARCHAR(MAX);

SET @COLS = STUFF((SELECT DISTINCT ',' + QUOTENAME(C.RN) 
            FROM (SELECT ID,TOKEN,COLS
    ,ROW_NUMBER() OVER (
        PARTITION BY ID ORDER BY (
                SELECT NULL
                )
        ) AS RN
FROM #EXAMPLE
CROSS APPLY (
    SELECT *
    FROM UDF_SPLITSTRING(COLS, ',')
    ) A) C
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @QUERY = 'SELECT ID,cols, ' + @COLS + ' FROM 
            (
                SELECT ID,TOKEN,cols
    ,ROW_NUMBER() OVER (
        PARTITION BY ID ORDER BY (
                SELECT NULL
                )
        ) AS RN
FROM #EXAMPLE
CROSS APPLY (
    SELECT *
    FROM UDF_SPLITSTRING(COLS, '','')
    ) A

           ) X
            PIVOT 
            (
                 MAX(TOKEN)
                FOR rn IN (' + @COLS + ')
            ) P '


exec(@QUERY)

output

产量

ID  cols                    1       2       3    4       5
1   HI,HELLO,BYE,TC         HI     HELLO    BYE  TC      NULL
2   WHAT,ARE,YOU,DOING,HERE WHAT    ARE     YOU  DOING   HERE

#1


5  

This is what you are expecting

这是你所期待的

Schema:

架构:

CREATE TABLE #EXAMPLE(ID INT PRIMARY KEY IDENTITY, COLS VARCHAR(255))
INSERT INTO #EXAMPLE(COLS) VALUES('HI,HELLO,BYE,TC')
INSERT INTO #EXAMPLE(COLS) VALUES('WHAT,ARE,YOU,DOING,HERE')

Do split those comma separated values into Rows and Apply pivot

将这些逗号分隔值拆分为Rows和Apply pivot

SELECT * FROM (
SELECT id
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2
, SPLT.CLMS.value('.','VARCHAR(MAX)') AS LIST FROM ( 
select id
, CAST( '<M>'+REPLACE(cols,',','</M><M>')+'</M>' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes('/M') AS SPLT(CLMS)
)A
PIVOT
(
    MAX(LIST) FOR ID2 IN ([1],[2],[3],[4],[5])
)PV

You will get result as

你会得到结果

+----+------+-------+-----+-------+------+
| id |  1   |   2   |  3  |   4   |  5   |
+----+------+-------+-----+-------+------+
|  1 | HI   | HELLO | BYE | TC    | NULL |
|  2 | WHAT | ARE   | YOU | DOING | HERE |
+----+------+-------+-----+-------+------+

Edit:

编辑:

And now you need to go for dynamic pivot,since There is no limit for values.

现在你需要进行动态调整,因为值没有限制。

DECLARE @COLS VARCHAR(MAX)='', @QRY VARCHAR(MAX)='';


SELECT @COLS =@COLS+'['+CAST( ID2 AS VARCHAR(10))+'],' FROM (
SELECT  DISTINCT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2  FROM ( 
select id, CAST( '<M>'+REPLACE(cols,',','</M><M>')+'</M>' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes('/M') AS SPLT(CLMS)
)A

SELECT @COLS = LEFT(@COLS,LEN(@COLS)-1)


SELECT @QRY =
'
SELECT * FROM (
SELECT id
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 1)) AS ID2
, SPLT.CLMS.value(''.'',''VARCHAR(MAX)'') AS LIST FROM ( 
select id, CAST( ''<M>''+REPLACE(cols,'','',''</M><M>'')+''</M>'' AS XML) AS XML_COL from #example E
)E
CROSS APPLY  E.XML_COL.nodes(''/M'') AS SPLT(CLMS)
)A
PIVOT
(
    MAX(LIST) FOR ID2 IN ('+@COLS+ ')
)PV'

EXEC( @QRY)

#2


1  

Dynamic version base on split string then pivot table

基于拆分字符串然后数据透视表的动态版本

Schema:

架构:

create table #example(id int primary key identity, cols varchar(255))
insert into #example(cols) values('HI,HELLO,BYE,TC')
insert into #example(cols) values('WHAT,ARE,YOU,DOING,HERE')

Calculate columns pivot

计算列枢轴

-- Calculate dynamic columns
;WITH temps AS 
(
  SELECT sd.* ,CAST('<x>' + replace(sd.cols, ',', '</x><x>') + '</x>' as xml) AS xmlText
  FROM #example sd
),
temps1 AS
(
   SELECT t.Id, t.cols, v.x.value('.','varchar(50)') AS Value
   FROM temps t
   CROSS APPLY 
     t.xmlText.nodes('/x') AS v(x)
)
SELECT @ColumnPivot =  STUFF((SELECT DISTINCT CONCAT(',COL',row_number() OVER(PARTITION BY t.id ORDER BY t.Value)) FROM temps1 t FOR XML PATH('')), 1,1,'')

PRINT @ColumnPivot

Then PIVOT table

然后是PIVOT表

 DECLARE @query nvarchar(max) = 
   CONCAT(N';WITH temps AS 
   (
      SELECT sd.* ,CAST(''<x>'' + replace(sd.cols, '','', ''</x><x>'') + ''</x>'' as xml) AS xmlText
      FROM #example sd
   ),
   temps1 AS
   (
      SELECT t.Id, t.cols, v.x.value(''.'' , ''varchar(50)'') AS Value
      FROM temps t
      CROSS APPLY 
         t.xmlText.nodes(''/x'') AS v(x)
   ),
   temps2 AS
   (
      SELECT t.* , CONCAT(''COL'',row_number() OVER(PARTITION BY t.id ORDER BY (select 1))) AS ColGroup
      FROM temps1 t
   )',
    N'SELECT Id, cols, ' , @ColumnPiVot,
  ' FROM
    (
       select * from temps2
    ) AS src
  PIVOT 
    (MAX(Value) FOR ColGroup IN (',@ColumnPiVot,')) AS pvt')
  PRINT @query
  exec sp_executesql  @query

DROP TABLE #example

Demo link: Rextester

演示链接:Rextester

#3


0  

          DECLARE @COLS AS NVARCHAR(MAX),
    @QUERY  AS NVARCHAR(MAX);

SET @COLS = STUFF((SELECT DISTINCT ',' + QUOTENAME(C.RN) 
            FROM (SELECT ID,TOKEN,COLS
    ,ROW_NUMBER() OVER (
        PARTITION BY ID ORDER BY (
                SELECT NULL
                )
        ) AS RN
FROM #EXAMPLE
CROSS APPLY (
    SELECT *
    FROM UDF_SPLITSTRING(COLS, ',')
    ) A) C
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @QUERY = 'SELECT ID,cols, ' + @COLS + ' FROM 
            (
                SELECT ID,TOKEN,cols
    ,ROW_NUMBER() OVER (
        PARTITION BY ID ORDER BY (
                SELECT NULL
                )
        ) AS RN
FROM #EXAMPLE
CROSS APPLY (
    SELECT *
    FROM UDF_SPLITSTRING(COLS, '','')
    ) A

           ) X
            PIVOT 
            (
                 MAX(TOKEN)
                FOR rn IN (' + @COLS + ')
            ) P '


exec(@QUERY)

output

产量

ID  cols                    1       2       3    4       5
1   HI,HELLO,BYE,TC         HI     HELLO    BYE  TC      NULL
2   WHAT,ARE,YOU,DOING,HERE WHAT    ARE     YOU  DOING   HERE