на основе ваших таблиц:
create table test_table
(
ProductId int
,Color varchar(100)
)
insert into test_table values (1, 'red, blue, green')
insert into test_table values (2, null)
insert into test_table values (3, 'purple, green')
создайте новую таблицу следующим образом:
CREATE TABLE Numbers
(
Number int not null primary key
)
, в котором есть строки, содержащие значения от 1 до 8000 или около того.
это вернет то, что вы хотите:
EDIT
Вот гораздо лучший запрос, немного измененный по сравнению с замечательным ответом @Christopher Klein:
Я добавил «LTRIM ()», чтобы пространства в списке цветов обрабатывались правильно: «красный, синий, зеленый». Его решение не требует пробелов "красный, синий, зеленый". Кроме того, я предпочитаю использовать свою собственную таблицу номеров и не использовать master.dbo.spt_values, это также позволяет удалить одну производную таблицу.
SELECT
ProductId, LEFT(PartialColor, CHARINDEX(',', PartialColor + ',')-1) as SplitColor
FROM (SELECT
t.ProductId, LTRIM(SUBSTRING(t.Color, n.Number, 200)) AS PartialColor
FROM test_table t
LEFT OUTER JOIN Numbers n ON n.Number<=LEN(t.Color) AND SUBSTRING(',' + t.Color, n.Number, 1) = ','
) t
РЕДАКТИРОВАТЬ КОНЕЦ
SELECT
ProductId, Color --,number
FROM (SELECT
ProductId
,CASE
WHEN LEN(List2)>0 THEN LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(',', List2, number+1)-number - 1)))
ELSE NULL
END AS Color
,Number
FROM (
SELECT ProductId,',' + Color + ',' AS List2
FROM test_table
) AS dt
LEFT OUTER JOIN Numbers n ON (n.Number < LEN(dt.List2)) OR (n.Number=1 AND dt.List2 IS NULL)
WHERE SUBSTRING(List2, number, 1) = ',' OR List2 IS NULL
) dt2
ORDER BY ProductId, Number, Color
вот мой набор результатов:
ProductId Color
----------- --------------
1 red
1 blue
1 green
2 NULL
3 purple
3 green
(6 row(s) affected)
это тот же порядок, который вы хотите ...