Vous semblez déterminé à utiliser un CTE, alors essayez ceci :
DECLARE @YourTable table (RowID int, Layout varchar(200))
INSERT @YourTable VALUES (1,'hello,world,welcome,to,tsql')
INSERT @YourTable VALUES (2,'welcome,to,stackoverflow')
;WITH SplitSting AS
(
SELECT
RowID,LEFT(Layout,CHARINDEX(',',Layout)-1) AS Part
,RIGHT(Layout,LEN(Layout)-CHARINDEX(',',Layout)) AS Remainder
FROM @YourTable
WHERE Layout IS NOT NULL AND CHARINDEX(',',Layout)>0
UNION ALL
SELECT
RowID,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
UNION ALL
SELECT
RowID,Remainder,null
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT * FROM SplitSting ORDER BY RowID
SORTIE :
RowID Part
----------- -----------------------
1 hello
1 world
1 welcome
1 to
1 tsql
2 welcome
2 to
2 stackoverflow
(8 row(s) affected)
voici un excellent article sur le fractionnement des chaînes dans SQL Server :"Arrays and Lists in SQL Server 2005 et au-delà, lorsque les paramètres de valeur de table ne suffisent pas" par Erland Sommarskog
MODIFIER voici une autre version (mais vous avez besoin d'un tableau de nombres) renvoie les mêmes résultats que ci-dessus :
;WITH SplitValues AS
(
SELECT
RowID,ListValue
FROM (SELECT
RowID, LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(',', List2, number+1)-number - 1))) AS ListValue
FROM (
SELECT RowID, ',' + Layout + ',' AS List2
FROM @YourTable
) AS dt
INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
WHERE SUBSTRING(List2, number, 1) = ','
) dt2
WHERE ListValue IS NOT NULL AND ListValue!=''
)
SELECT * FROM SplitValues
voir ici pour un tableau de nombres :Quelle est la meilleure façon de créer et de remplir un tableau de nombres ?