Sorry if the title is bad. But I do not know how to address the problem.
I've been really struggling with a query in sql. I do not know if this question has been asked before. But I need to get the first column that is not null. I have a table like this:
ID 0 1 2 3 4 5 6 7 8 9
59 NULL NULL NULL NULL NULL NULL NULL NULL NULL text1
185 NULL NULL NULL NULL NULL text1 text2 text3 text4 text5
428 NULL NULL NULL NULL NULL NULL text1 text2 text3 text4
53 NULL NULL NULL NULL NULL NULL NULL NULL text1 text2
452 NULL NULL NULL NULL NULL NULL NULL NULL NULL text1
267 text1 text2 text3 text4 text5 text6 text7 text8 text9 text10
And I would like the output to be like this:
ID 0 1 2 3 4 5 6 7 8 9
59 text1 NULL NULL NULL NULL NULL NULL NULL NULL NULL
185 text1 text2 text3 text4 text5 NULL NULL NULL NULL NULL
428 text1 text2 text3 text4 NULL NULL NULL NULL NULL NULL
53 text1 text2 NULL NULL NULL NULL NULL NULL NULL NULL
452 text1 NULL NULL NULL NULL NULL NULL NULL NULL NULL
267 text1 text2 text3 text4 text5 text6 text7 text8 text9 text10
The ID column is unique per row.
My failed attempt was to create a scalared function and run it for each column. The function looks like this:
CREATE FUNCTION GetCulumnsThatIsNotNull
(
#column1 VARCHAR(500),
#column2 VARCHAR(500),
#column3 VARCHAR(500),
#column4 VARCHAR(500),
#column5 VARCHAR(500),
#column6 VARCHAR(500),
#column7 VARCHAR(500),
#column8 VARCHAR(500),
#column9 VARCHAR(500),
#column10 VARCHAR(500)
)
RETURNS VARCHAR(500)
AS
BEGIN
RETURN
COALESCE(#column1,
COALESCE(#column2,
COALESCE(#column3,
COALESCE(#column4,
COALESCE(#column5,
COALESCE(#column6,
COALESCE(#column8,
COALESCE(#column9,
COALESCE(#column10,null)))))))))
END
But the problem with this function is that it is just picking the first column that are null. So the result get like this:
ID 0 1 2 3 4 5 6 7 8 9
59 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
185 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
428 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
53 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
452 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
267 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1
Any suggestions?
EDIT
This will not work ether.
COALESCE(pvt.[0],
pvt.[1],
pvt.[2],
pvt.[3],
pvt.[4],
pvt.[5],
pvt.[6],
pvt.[7],
pvt.[8],
pvt.[9])
Because it will result in the same output
I would normalize the data in a view or CTE or something, then run an ordinary pivot. This way, should you ever actually normalize the table, you'll be able to reuse code.
-- Setup test data
declare #texts table (
ID int not null primary key
, Col0 varchar(10) null
, Col1 varchar(10) null
, Col2 varchar(10) null
, Col3 varchar(10) null
, Col4 varchar(10) null
, Col5 varchar(10) null
, Col6 varchar(10) null
, Col7 varchar(10) null
, Col8 varchar(10) null
, Col9 varchar(10) null
)
insert into #texts select 59, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1'
insert into #texts select 185, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2', 'text3', 'text4', 'text5'
insert into #texts select 428, NULL, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2', 'text3', 'text4'
insert into #texts select 53, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1', 'text2'
insert into #texts select 452, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'text1'
insert into #texts select 267, 'text1', 'text2', 'text3', 'text4', 'text5', 'text6', 'text7', 'text8', 'text9', 'text10'
-- Normalize and get new column in a CTE
;with cte as (
select *
, row_number() over (partition by ID order by Col) - 1 as NewCol
from (
select ID, 0 as Col
, (select Col0 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 1 as Col
, (select Col1 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 2 as Col
, (select Col2 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 3 as Col
, (select Col3 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 4 as Col
, (select Col4 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 5 as Col
, (select Col5 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 6 as Col
, (select Col6 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 7 as Col
, (select Col7 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 8 as Col
, (select Col8 from #texts where ID = a.ID) as Val
from #texts a
union all
select ID, 9 as Col
, (select Col9 from #texts where ID = a.ID) as Val
from #texts a
) as b
where b.Val is not null
)
-- Run a pivot of the CTE
select ID
, (select Val from cte where ID = a.ID and NewCol = 0) as Col0
, (select Val from cte where ID = a.ID and NewCol = 1) as Col1
, (select Val from cte where ID = a.ID and NewCol = 2) as Col2
, (select Val from cte where ID = a.ID and NewCol = 3) as Col3
, (select Val from cte where ID = a.ID and NewCol = 4) as Col4
, (select Val from cte where ID = a.ID and NewCol = 5) as Col5
, (select Val from cte where ID = a.ID and NewCol = 6) as Col6
, (select Val from cte where ID = a.ID and NewCol = 7) as Col7
, (select Val from cte where ID = a.ID and NewCol = 8) as Col8
, (select Val from cte where ID = a.ID and NewCol = 9) as Col9
from cte a
group by ID
order by ID
select *
from
(
select T.ID, C.C, row_number() over(partition by T.ID order by C.N) - 1 as rn
from #T as T
cross apply (values (C0, 0),(C1, 1),(C2, 2),(C3, 3),(C4, 4),
(C5, 5),(C6, 6),(C7, 7),(C8, 8),(C9, 9)) as C(C, N)
where C.C is not null
) as T
pivot
(
min(C) for rn in ([0],[1],[2],[3],[4],[5],[6],[7],[8],[9])
) as P
Try on SE-Data
Related
I am going to split one column of my table to multiple columns. The fields are separated by comma and I used the split_part. The problem that I faced is the length of string are not same and after splitting they are located from column 1 to column N.
Column
a,b,c,d,e,f
b,c,e,f
c,d,e,f
my output is:
col1 col2 col3 col4 col5 col6
a b c d e f
b c e f
c d e f
but I want to have an output like this
col1 col2 col3 col4 col5 col6
a b c d e f
b c e f
c d e f
Table and data def shamelessly stolen from #xehpuk
CREATE TABLE split_column (
id integer PRIMARY KEY,
col text NOT NULL
)
data
INSERT INTO split_column (id, col) VALUES
(1, 'a,b,c,d,e,f'),
(2, 'b,c,e,f'),
(3, 'c,d,e,f')
Use Case statements in query:
select case when position('a' in col)::bool then 'a' end as col1,
case when position('b' in col)::bool then 'b' end as col2,
case when position('c' in col)::bool then 'c' end as col3,
case when position('d' in col)::bool then 'd' end as col4,
case when position('e' in col)::bool then 'e' end as col5,
case when position('f' in col)::bool then 'f' end as col6
from aaa.split_column
col1
col2
col3
col4
col5
col6
a
b
c
d
e
f
null
b
c
null
e
f
null
null
c
d
e
f
Given this table:
CREATE TABLE split_column (
id integer PRIMARY KEY,
col text NOT NULL
)
And this data:
INSERT INTO split_column (id, col) VALUES
(1, 'a,b,c,d,e,f'),
(2, 'b,c,e,f'),
(3, 'c,d,e,f')
The first row contains all values:
SELECT string_to_array(col, ',') AS values
FROM split_column
ORDER BY id
LIMIT 1
values
{a,b,c,d,e,f}
We use it to create a mapping from col1..colN to the values:
WITH complete AS (
SELECT string_to_array(col, ',') AS values
FROM split_column
ORDER BY id
LIMIT 1
)
SELECT 'col' || value.ordinality AS key, value
FROM complete, unnest(complete.values) WITH ORDINALITY AS value
key
value
col1
a
col2
b
col3
c
col4
d
col5
e
col6
f
We aggregate the rows to JSON objects:
WITH complete AS (
SELECT string_to_array(col, ',') AS values
FROM split_column
ORDER BY id
LIMIT 1
), map AS (
SELECT 'col' || value.ordinality AS key, value
FROM complete, unnest(complete.values) WITH ORDINALITY AS value
)
SELECT id, jsonb_object_agg(map.key, map.value) AS object
FROM split_column, string_to_table(col, ',') AS col
JOIN map
ON col = map.value
GROUP BY id
ORDER BY id
id
object
1
{"col1": "a", "col2": "b", "col3": "c", "col4": "d", "col5": "e", "col6": "f"}
2
{"col2": "b", "col3": "c", "col5": "e", "col6": "f"}
3
{"col3": "c", "col4": "d", "col5": "e", "col6": "f"}
And then we "destructure" them back into records:
WITH complete AS (
SELECT string_to_array(col, ',') AS values
FROM split_column
ORDER BY id
LIMIT 1
), map AS (
SELECT 'col' || value.ordinality AS key, value
FROM complete, unnest(complete.values) WITH ORDINALITY AS value
), agg AS (
SELECT id, jsonb_object_agg(map.key, map.value) AS object
FROM split_column, string_to_table(col, ',') AS col
JOIN map
ON col = map.value
GROUP BY id
)
SELECT agg.id, cols.*
FROM agg, jsonb_to_record(agg.object) AS cols(col1 text, col2 text, col3 text, col4 text, col5 text, col6 text)
ORDER BY id
id
col1
col2
col3
col4
col5
col6
1
a
b
c
d
e
f
2
b
c
e
f
3
c
d
e
f
db<>fiddle
I am trying to pivot rows into columns with Tsql and also eliminate Nulls. How do I do this? My current query:
IF OBJECT_ID(N'tempdb..#test_data') IS NOT NULL drop table #test_data
create table #test_data (
question_caption varchar(max),
[0] varchar(max),
[1] varchar(max),
[2] varchar(max),
[3] varchar(max))
insert #test_data values('q1','abc',Null,Null,Null)
insert #test_data values('q2',Null,'def',Null,Null)
insert #test_data values('q3',Null,Null,'ghi',Null)
insert #test_data values('q4',Null,Null,Null,'jkl')
select * from #test_data
pivot (
Max([0])
For question_caption in ([0],[1],[2],[3])
) as PivotTable
Output:
question_caption 0 1 2 3
q1 abc NULL NULL NULL
q2 NULL def NULL NULL
q3 NULL NULL ghi NULL
q4 NULL NULL NULL jkl
What I want:
q1 q2 q3 q4
abc def ghi jkl
How can I achieve this? The above query has the error:
Msg 265, Level 16, State 1, Line 4
The column name "0" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
I have tried multiple Pivot examples, but all of them have resulted in one error or another.
You can do with a simple max case:
select [q1]=max(case when question_caption = 'q1' then [0] else null end),
[q2]=max(case when question_caption = 'q2' then [1] else null end),
[q3]=max(case when question_caption = 'q3' then [2] else null end),
[q4]=max(case when question_caption = 'q4' then [3] else null end)
from #test_data
or the pivot:
select [q1], [q2], [q3], [q4]
from ( select question_caption,
coalesce([0],[1],[2],[3])
from #test_data
) s (c, v)
pivot (max(v) for c in ([q1], [q2], [q3], [q4])) p
drop table #temp
Create Table #Temp
(
col1 Varchar(20),
col2 Varchar(20),
Col3 Varchar(50),
col4 Varchar(20)
)
Select * From #Temp
Insert Into #Temp(col1)
Select * From SplitDelimiterString('123,456', ',')
Insert Into #Temp(col2)
Select * From SplitDelimiterString('abc,def', ',')
Insert Into #Temp(Col3)
Select * From SplitDelimiterString('fff,ggg', ',')
Insert Into #Temp(col4)
Select * From SplitDelimiterString('520002,520003', ',')
Select * From #Temp
FYI, SplitDelimiterString is a function.
-- Code for SplitDelimiterString
Create FUNCTION [dbo].[SplitDelimiterString] (#StringWithDelimiter VARCHAR(8000), #Delimiter VARCHAR(8))
RETURNS #ItemTable TABLE (Item VARCHAR(8000))
AS
BEGIN
DECLARE #StartingPosition INT;
DECLARE #ItemInString VARCHAR(8000);
SELECT #StartingPosition = 1;
--Return if string is null or empty
IF LEN(#StringWithDelimiter) = 0 OR #StringWithDelimiter IS NULL RETURN;
WHILE #StartingPosition > 0
BEGIN
--Get starting index of delimiter .. If string
--doesn't contain any delimiter than it will returl 0
SET #StartingPosition = CHARINDEX(#Delimiter,#StringWithDelimiter);
--Get item from string
IF #StartingPosition > 0
SET #ItemInString = SUBSTRING(#StringWithDelimiter,0,#StartingPosition)
ELSE
SET #ItemInString = #StringWithDelimiter;
--If item isn't empty than add to return table
IF( LEN(#ItemInString) > 0)
INSERT INTO #ItemTable(Item) VALUES (#ItemInString);
--Remove inserted item from string
SET #StringWithDelimiter = SUBSTRING(#StringWithDelimiter,#StartingPosition +
LEN(#Delimiter),LEN(#StringWithDelimiter) - #StartingPosition)
--Break loop if string is empty
IF LEN(#StringWithDelimiter) = 0 BREAK;
END
RETURN
END
-- The result set is
Col1 Col2 Col3 Col4
123 NULL NULL NULL
456 NULL NULL NULL
NULL abc NULL NULL
NULL def NULL NULL
NULL NULL fff NULL
NULL NULL ggg NULL
NULL NULL NULL 520002
NULL NULL NULL 520003
-- I need a result set like
-- The result set is
col1 col2 col3 col4
123 abc fff 520002
456 def ggg 520003
Please help.
--- Figured out my self. Thanks to #liebs19 for logic
BEGIN TRAN
Create Table #Temp1
(
RowID int not null identity(1,1) primary key,
col1 Varchar(20),
)
Create Table #Temp2
(
RowID int not null identity(1,1) primary key,
col2 Varchar(20),
)
Create Table #Temp3
(
RowID int not null identity(1,1) primary key,
col3 Varchar(20),
)
Create Table #Temp4
(
RowID int not null identity(1,1) primary key,
col4 Varchar(20),
)
Insert Into #Temp1(col1)
Select * From SplitDelimiterString('123,456', ',')
Insert Into #Temp2(col2)
Select * From SplitDelimiterString('abc,def', ',')
Insert Into #Temp3(Col3)
Select * From SplitDelimiterString('fff,ggg', ',')
Insert Into #Temp4(col4)
Select * From SplitDelimiterString('520002,520003', ',')
Select #Temp1.Col1, #Temp2.col2, #Temp3.Col3, #Temp4.Col4
From #Temp1
Inner Join #Temp2 ON #Temp1.RowID = #Temp2.RowID
Inner Join #Temp3 ON #Temp1.RowID = #Temp3.RowID
Inner Join #Temp4 ON #Temp1.RowID = #Temp4.RowID
ROLLBACK TRAN
-- This is the output finally I am looking for.
col1 col2 col3 col4
123 abc fff 520002
456 def ggg 520003
.
I'm trying to anonymize all the data in my database, so I'm renaming all the people in it. I asked a similar question earlier, and was told to use NewID to force the creation of a new value per updated row, but in this situation it doesn't seem to be working.
What am I doing wrong?
-- Create Table Customer
CREATE TABLE #FirstName
(
ID int,
FirstName nvarchar(255) NULL,
Gender nvarchar(255) NULL
)
CREATE TABLE #LastName (
ID int,
LastName nvarchar(255)
)
-- BULK INSERT to import data from Text or CSV File
BULK INSERT #FirstName
FROM 'C:\Users\jhollon\Desktop\tmp\names\firstnames.lined.txt'
WITH
(
FIRSTROW = 1,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
BULK INSERT #LastName
FROM 'C:\Users\jhollon\Desktop\tmp\names\lastnames.lined.txt'
WITH
(
FIRSTROW = 1,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
/*SELECT FirstName FROM #FirstName WHERE ID = (
SELECT RandomNumber FROM (
SELECT ABS(CHECKSUM(NewID())) % 1500 AS RandomNumber FROM tblTenant WHERE Sex = '1'
) AS A
);*/
UPDATE tblTenant SET TenantName = (
SELECT LastName + ', ' + FirstName FROM
(SELECT UPPER(FirstName) as FirstName FROM #FirstName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 500 + 1501)) AS A,
(SELECT LastName FROM #LastName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 200 + 1)) as B
) WHERE Sex = '2';
UPDATE tblTenant SET TenantName = (
SELECT LastName + ', ' + FirstName FROM
(SELECT UPPER(FirstName) as FirstName FROM #FirstName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 500 + 1)) AS A,
(SELECT LastName FROM #LastName WHERE ID = (SELECT ABS(CHECKSUM(NewID())) % 200 + 1)) as B
) WHERE Sex = '1';
DROP TABLE #FirstName;
DROP TABLE #LastName;
Correct. The subquery is evaluated once which is as advertised ("cachable scalar subquery")
Try this which uses NEWID as a derived table
UPDATE T
SET
TenantName = L.LastName + ', ' + F.FirstName
FROM
tblTenant T
CROSS APPLY
(SELECT TOP 1 UPPER(FirstName) as FirstName FROM #FirstName
WHERE CHECKSUM(NEWID()) <> T.ID
ORDER BY NEWID()) F
CROSS APPLY
(SELECT TOP 1 LastName FROM #LastName
WHERE CHECKSUM(NEWID()) <> T.ID
ORDER BY NEWID()) L
I'm not sure I understand your question, but if you want the ID to be unique values, you can make it an identity column.
Ex:
[ID] [int] IDENTITY(1,1) NOT NULL
The code below demonstrates that without an inner to outer correlation, that the old name is not guaranteed to differ from the new name when using the CROSS APPLY answer above.
WHERE F.Id <> T.Id ORDER BY NEWID() would be better within the FirstName CROSS APPLY
USE tempdb
GO
IF OBJECT_ID('tblTenant') IS NOT NULL
DROP TABLE tblTenant
GO
CREATE TABLE tblTenant
(
Id int,
FirstName nvarchar(20),
LastName nvarchar(20),
Gender bit
)
INSERT INTO tblTenant
VALUES (1, 'Bob' , 'Marley', 1),
(2, 'Boz' , 'Skaggs', 1)
SELECT DISTINCT FirstName
INTO #FirstNames
FROM tblTenant
SELECT DISTINCT LastName
INTO #LastNames
FROM tblTenant
-- There is a probability > 0 that a tenant's new name = tenants old name
SELECT
OldFirst = T.FirstName,
OldLast = T.LastName,
NewFirst = F.FirstName,
NewLast = L.LastName
FROM
tblTenant T
CROSS APPLY
(
SELECT TOP 1 UPPER(FirstName) AS FirstName
FROM #FirstNames
WHERE CHECKSUM(NEWID()) <> T.ID
ORDER BY NEWID()
) F
CROSS APPLY
(
SELECT TOP 1 LastName
FROM #LastNames
WHERE CHECKSUM(NEWID()) <> T.ID
ORDER BY NEWID()
) L
From the table below, how can I convert the Values column into multiple columns, populated with individual values that are currently separated by commas? Before the conversion:
Name Values
---- ------
John val,val2,val3
Peter val5,val7,val9,val14
Lesli val8,val34,val36,val65,val71,val
Amy val3,val5,val99
The result of the conversion should look like:
Name Col1 Col2 Col3 Col4 Col5 Col6
---- ---- ---- ---- ---- ---- ----
John val val2 val3
Peter val5 val7 val9 val14
Lesli val8 val34 val36 val65 val71 val
Amy val3 val5 val99
First, what database product and version are you using? If you are using SQL Server 2005 and later, you can write a Split user-defined function like so:
CREATE FUNCTION [dbo].[Split]
(
#DelimitedList nvarchar(max)
, #Delimiter varchar(2) = ','
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(#DelimitedList, DataLength(#Delimiter)) <> #Delimiter Then #Delimiter Else '' End
+ #DelimitedList
+ Case When Right(#DelimitedList, DataLength(#Delimiter)) <> #Delimiter Then #Delimiter Else '' End
As List
, DataLength(#Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP (Coalesce(Len(#DelimitedList),1)) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.objects As c1
Cross Join sys.columns As c2
)
Select CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(#Delimiter, CL.list, N.Value + 1)
- ( CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value < Len(CL.List)
And Substring(CL.List, N.Value, CL.DelimiterLen) = #Delimiter
)
You can then split out the values in you want using something akin to:
Select Name, Values
From Table1 As T1
Where Exists (
Select 1
From Table2 As T2
Cross Apply dbo.Split (T1.Values, ',') As T1Values
Cross Apply dbo.Split (T2.Values, ',') As T2Values
Where T2.Values.Value = T1Values.Value
And T1.Name = T2.Name
)
Here is a solution that uses a recursive cte to generate a "table of numbers" (courtesy of Itzik Ben-Gan), which is useful for all manner of problems including string splitting, and PIVOT. SQL Server 2005 onwards. Full table create, insert and select script included.
CREATE TABLE dbo.Table1
(
Name VARCHAR(30),
[Values] VARCHAR(128)
)
GO
INSERT INTO dbo.Table1 VALUES ('John', 'val,val2,val3')
INSERT INTO dbo.Table1 VALUES ('Peter', 'val5,val7,val9,val14')
INSERT INTO dbo.Table1 VALUES ('Lesli', 'val8,val34,val36,val65,val71,val')
INSERT INTO dbo.Table1 VALUES ('Amy', 'val3,val5,val99')
GO
SELECT * FROM dbo.Table1;
GO
WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3)
SELECT Name, [1] AS Column1, [2] AS Column2, [3] AS Column3, [4] AS Column4, [5] AS Column5, [6] AS Column6, [7] AS Column7
FROM
(SELECT Name,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY nums.n) AS PositionInList,
LTRIM(RTRIM(SUBSTRING(valueTable.[Values], nums.n, charindex(N',', valueTable.[Values] + N',', nums.n) - nums.n))) AS [Value]
FROM Numbers AS nums INNER JOIN dbo.Table1 AS valueTable ON nums.n <= CONVERT(int, LEN(valueTable.[Values])) AND SUBSTRING(N',' + valueTable.[Values], n, 1) = N',') AS SourceTable
PIVOT
(
MAX([VALUE]) FOR PositionInList IN ([1], [2], [3], [4], [5], [6], [7])
) AS Table2
GO
--DROP TABLE dbo.Table1
Which converts this output
Name Values
John val,val2,val3
Peter val5,val7,val9,val14
Lesli val8,val34,val36,val65,val71,val
Amy val3,val5,val99
to
Name Column1 Column2 Column3 Column4 Column5 Column6 Column7
Amy val3 val5 val99 NULL NULL NULL NULL
John val val2 val3 NULL NULL NULL NULL
Lesli val8 val34 val36 val65 val71 val NULL
Peter val5 val7 val9 val14 NULL NULL NULL