Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting comma separated values into separate or different columns

Tags:

sql

sql-server

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

enter image description here

like image 542
natwar lal Avatar asked Apr 20 '17 05:04

natwar lal


People also ask

How to split comma separated values into different columns in Excel?

Use Excel Flash Fill to Split Comma Separated Values into Different Columns We can type a portion of the comma-separated data in a different column and then apply the Flash Fill feature to get the rest of the data of the same pattern. Type ‘ Dates ’ in Cell C5.

How to insert comma between rows and columns in Excel?

2. In the Split Cells dialog box, select Split to Rows or Split to Columns in the Type section as you need. And in the Specify a separator section, select the Other option, enter the comma symbol into the textbox, and then click the OK button. See screenshot:

What is comma separated values in CSV?

Comma-separated values. A CSV file stores tabular data (numbers and text) in plain text. Each line of the file is a data record. Each record consists of one or more fields, separated by commas. The use of the comma as a field separator is the source of the name for this file format .

What is a comma separated text file?

In computing, a comma-separated values (CSV) file is a delimited text file that uses a comma to separate values. A CSV file stores tabular data (numbers and text) in plain text. Each line of the file is a data record.


2 Answers

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

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)
like image 108
Shakeer Mirza Avatar answered Oct 20 '22 00:10

Shakeer Mirza


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

 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

like image 30
TriV Avatar answered Oct 19 '22 23:10

TriV