I have the following three different strings which needs to split into three different columns.
Example:
String 1:
Declare @
You haven't given any criteria for joining the values together for each of the rows of columns so I've just joined them in descending order. This solution can handle any number of items in the lists but if the number gets too high you may need to use the MAX RECURSION
query hint.
DECLARE @strA NVARCHAR(MAX) = 'A1,A2,A3';
DECLARE @strB NVARCHAR(MAX) = 'B1,B2,B3,B4';
DECLARE @strC NVARCHAR(MAX) = 'C1,C2,C3';
WITH stringData AS (
--each group of comma separate values with a group identifier
SELECT 'a' AS grp, @strA AS strng
UNION ALL
SELECT 'b' AS grp, @strB
UNION ALL
SELECT 'c' AS grp, @strC
),
splitStrings AS (
--a recursive CTE to split the comma separated values
SELECT grp, CAST('' AS NVARCHAR(MAX)) AS item,
strng AS cText
FROM stringData
UNION ALL
SELECT grp,
CASE
WHEN CHARINDEX(N',',cText,0)>0 THEN LEFT(cText,CHARINDEX(N',',cText,0)-1) --SUBSTRING(cText,0,CHARINDEX(N',',cText,0))
ELSE cText
END,
RIGHT(cText,LEN(cText)-CHARINDEX(N',',cText,0))
FROM splitStrings
WHERE cText!=item
)
SELECT grp,
item,
ROW_NUMBER() OVER(PARTITION BY grp ORDER BY item) AS rnum
INTO #stringValues --put the results in a temp table so we don't need to execute the recursive CTE more than once
FROM splitStrings
WHERE len(item)>0;
DECLARE @maxNum INT = (SELECT MAX(rnum) FROM #stringValues);
--join the values together
WITH allNums AS (
SELECT 1 AS num
UNION ALL
SELECT num+1
FROM allNums
WHERE num<@maxNum
)
SELECT sa.item AS colA,
sb.item AS colB,
sc.item AS colC
FROM allNums
LEFT JOIN #stringValues AS sa ON sa.rnum=allNums.num AND sa.grp='A'
LEFT JOIN #stringValues AS sb ON sb.rnum=allNums.num AND sb.grp='B'
LEFT JOIN #stringValues AS sc ON sc.rnum=allNums.num AND sc.grp='C'
DROP TABLE #stringValues;