If we assume that the value will always contain 8 values, then you can could use some ugly CHARINDEX
and SUBSTRING
s, and STUFF
for the final column:
DECLARE @YourString varchar(8000) = 'MY|NAME|IS|ABCD|ZHGGG|GSHHS|ASDF|ASDF';
SELECT SUBSTRING(V.YourString,1,CI1.I-1) AS Col1,
SUBSTRING(V.YourString,CI1.I+1,CI2.I-CI1.I-1) AS Col2,
SUBSTRING(V.YourString,CI2.I+1,CI3.I-CI2.I-1) AS Col3,
SUBSTRING(V.YourString,CI3.I+1,CI4.I-CI3.I-1) AS Col4,
SUBSTRING(V.YourString,CI4.I+1,CI5.I-CI4.I-1) AS Col5,
SUBSTRING(V.YourString,CI5.I+1,CI6.I-CI5.I-1) AS Col6,
SUBSTRING(V.YourString,CI6.I+1,CI7.I-CI6.I-1) AS Col7,
STUFF(V.YourString,1,CI7.I,'') AS Col8
FROM (VALUES(@YourString))V(YourString)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString)))CI1(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI1.I+1)))CI2(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI2.I+1)))CI3(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI3.I+1)))CI4(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI4.I+1)))CI5(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI5.I+1)))CI6(I)
CROSS APPLY (VALUES(CHARINDEX('|',V.YourString,CI6.I+1)))CI7(I);
With a string splitter (such as DelimitedSplit8K
), that returns the original position, and then use that to conditionally aggregate:
DECLARE @YourString varchar(8000) = 'MY|NAME|IS|ABCD|ZHGGG|GSHHS|ASDF|ASDF';
SELECT MAX(CASE DS.ItemNumber WHEN 1 THEN DS.Item END) AS Col1,
MAX(CASE DS.ItemNumber WHEN 2 THEN DS.Item END) AS Col2,
MAX(CASE DS.ItemNumber WHEN 3 THEN DS.Item END) AS Col3,
MAX(CASE DS.ItemNumber WHEN 4 THEN DS.Item END) AS Col4,
MAX(CASE DS.ItemNumber WHEN 5 THEN DS.Item END) AS Col5,
MAX(CASE DS.ItemNumber WHEN 6 THEN DS.Item END) AS Col6,
MAX(CASE DS.ItemNumber WHEN 7 THEN DS.Item END) AS Col7,
MAX(CASE DS.ItemNumber WHEN 8 THEN DS.Item END) AS Col8
FROM (VALUES(@YourString))V(YourString)
CROSS APPLY fn.DelimitedSplit8K(V.YourString,'|') DS
GROUP BY V.YourString; --Or, more likely, your ID.