I have the following table definition
CREATE TABLE _Table
(
[Pat] NVARCHAR(8),
[Codes] NVARCHAR(50),
[C1] NVARCHAR(6),
[C2] NVARCHAR(6),
[C3] NVARCHAR(6),
[C4] NVARCHAR(6),
[C5] NVARCHAR(6)
);
GO
INSERT INTO _Table ([Pat], [Codes], [C1], [C2], [C3], [C4], [C5])
VALUES
('Pat1', 'U212,Y973,Y982', null, null, null, null, null),
('Pat2', 'M653', null, null, null, null, null),
('Pat3', 'U212,Y973,Y983,Z924,Z926', null, null, null, null, null);
GO
Now, I would like to split the codes for each row and populate the Cn
columns so we end up with
Pat Codes C1 C2 C3 C4 C5
Pat1 'U212,Y973,Y982' U212 Y973 Y982 NULL NULL
Pat2 'M653' M653 NULL NULL NULL NULL
Pat3 'U212,Y973,Y983,Z924,Z926' U212 Y973 Y983 Z924 Z926
I am looking at dynamic SQL but is there a better way...
I have started down the CTE route, but I am weak here. I am essentially looping, removing the first comma separated code and using left to get that code and selected it as C1
.
;WITH tmp([Pat], [Codes], [C1], [C2], [C3], [C4], [C5]) AS
(
SELECT
Pat,
STUFF(Codes, 1, CHARINDEX(',', Codes + ','), ''),
LEFT(Codes, CHARINDEX(',', Codes + ',') - 1),
[C2],
[C3],
[C4],
[C5]
FROM _Table
UNION all
SELECT
Pat,
STUFF(Codes, 1, CHARINDEX(',', Codes + ','), ''),
LEFT(Codes, CHARINDEX(',', Codes + ',') - 1),
[C2],
[C3],
[C4],
[C5]
FROM _Table
WHERE
Codes > ''
)
SELECT Pat, Codes, [C1], [C2], [C3], [C4], [C5]
FROM tmp
ORDER BY Pat
This works for one code, but how do I do all 5? Note, in practice this could increase to N codes.