Sposobów „dobierania” się do danych oddzielonych przecinkiem, średnikiem, spacją i innymi jest wiele, jednym z dobrych pomysłów jest użycie potęgi XML.
Mamy tabelę, przykładowo dane oddzieliłem przecinkiem ale może to być inny znak.
CREATE TABLE #test (id INT IDENTITY(1,1),tekst VARCHAR(255))
go
INSERT #test(tekst)
SELECT'jeden,dwa,trzy,cztery,pięć,sześć,siedem,osiem,dziewięć'
UNION ALL
SELECT'112,134,12345,1234,1789,234,28'
Rozwiązanie problemu
SELECT id,
tx.parser.value('@element', 'varchar(100)')AS elementy
FROM(SELECT id,
CONVERT(XML,'<rekord element="'
+ REPLACE(tekst,',','"/><rekord element="')+'"/>')
AS parser
FROM #test)AS t
CROSS APPLY t.parser.nodes('/rekord')AS tx (parser)
Dostajemy wynik
id elementy
--------------------------
1 jeden
1 dwa
1 trzy
1 cztery
1 pięć
1 sześć
1 siedwm
1 osiem
1 dziewięć
2 112
2 134
2 12345
2 1234
2 1789
2 234
2 28A teraz w drugą stronę
Zrobimy tabelę #test2
SELECT id,
tx.parser.value('@element', 'varchar(100)')AS elementy
into #test2
FROM(SELECT id,
CONVERT(XML,'<rekord element="'
+ REPLACE(tekst,',','"/><rekord element="')+'"/>')
AS parser
FROM #test)AS t
CROSS APPLY t.parser.nodes('/rekord')AS tx (parser)
SELECT * FROM #test2
id elementy
----------- ----------
1 jeden
1 dwa
1 trzy
1 cztery
1 pięć
1 sześć
1 siedem
1 osiem
1 dziewięć
2 112
2 134
2 12345
2 1234
2 1789
2 234
2 28
Zapytnie
SELECT p1.id,
( SELECT elementy + ','
FROM #test2 p2
WHERE p2.id = p1.id
ORDER BY id
FOR XML PATH('') ) AS tekst
FROM #test2 p1
GROUP BY id
lub
SELECT DISTINCT id,tekst
FROM #test2 p1
CROSS APPLY ( SELECT elementy + ','
FROM #test2 p2
WHERE p2.id = p1.id
ORDER BY id
FOR XML PATH('') ) D ( tekst )
Wynik
id tekst
----------------------------------------------------------------------
1 jeden,dwa,trzy,cztery,pięć,sześć,siedem,osiem,dziewięć,
2 112,134,12345,1234,1789,234,28,
Ta metoda jest fajna w duecie z funkcją STUFF, dzięki której można łatwo pozbyć się pierwszego przecinka (ja zawsze zaczynam konkatenację od przecinka właśnie z tego powodu). Ale metoda ma też poważne ograniczenia - wystarczy, że trafi się nam jakiś znaczek kodowany jako specjalna encja w XMLu i dostaniemy krzaczki a la & :-)
OdpowiedzUsuń