请尝试其中一种 -
DECLARE @temp TABLE
(
id INT
, string NVARCHAR(200)
)
DECLARE @Separator CHAR(1)
SELECT @Separator = ','
INSERT INTO @temp (id, string)
VALUES
(1, 'aaa,eee,ccc,ggg,hhh,bbb'),
(2, 'ggg,bbb,ccc,ggg,aaa,bbb,bbb'),
(3, 'ddd,ggg,eee')
1.XML
SELECT
id = p.value('(./n)[1]', 'INT')
, name = p.value('(./s)[1]', 'NVARCHAR(200)')
FROM (
SELECT field = CAST('<r><s>' + REPLACE(SUBSTRING(',' + t.string + ',', 2, LEN(',' + t.string + ',')), @Separator, '</s><n>' + CAST(t.id AS VARCHAR(10)) + '</n></r><r><s>') + '</s></r>' AS XML)
FROM @temp t
) d
CROSS APPLY field.nodes('/r') t(p)
WHERE t.p.exist('n') = 1
2. spt_values
SELECT
t.id
, name =
SUBSTRING(
',' + t.string + ','
, number + 1
, CHARINDEX(@Separator, ',' + t.string + ',', number + 1) - number - 1)
FROM @temp t
CROSS JOIN [master].dbo.spt_values n
WHERE [type] = 'p'
AND number <= LEN(',' + t.string + ',') - 1
AND SUBSTRING(',' + t.string + ',', number, 1) = @Separator
3.虽然
DECLARE @items TABLE
(
id INT
, name NVARCHAR(50)
)
DECLARE
@id INT
, @string NVARCHAR(2000)
, @pos INT
DECLARE cur CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT id, string
FROM @temp
OPEN cur
FETCH NEXT FROM cur INTO @id, @string
WHILE @@FETCH_STATUS = 0 BEGIN
WHILE LEN(@string) > 0 BEGIN
SELECT @pos = CHARINDEX(@Separator, @string, 1)
IF @pos = 0
SELECT @pos = LEN(@string)
INSERT INTO @items (id, name)
SELECT @id, SUBSTRING(@string, 1, @pos - 1)
SELECT @string = SUBSTRING(@string, @pos + 1, LEN(@string) - @pos)
END
FETCH NEXT FROM cur INTO @id, @string
END
CLOSE cur
DEALLOCATE cur
SELECT
i.id
, i.name
FROM @items i
WHERE name != ''
4. CTE
;WITH a AS
(
SELECT
id
, start_pos = 1
, end_pos = CHARINDEX(@Separator, t.string)
, t.string
FROM @temp t
UNION ALL
SELECT
id
, end_pos + 1
, CHARINDEX(@Separator, string, end_pos + 1)
, string
FROM a
WHERE end_pos > 0
)
SELECT
d.id
, d.name
FROM (
SELECT
a.id
, name = SUBSTRING(
string
, start_pos
, ABS(end_pos - start_pos)
)
FROM a
) d
WHERE d.name != ''