Spojení textových řetězců z více sloupců na řádek můžeme v SQL Serveru v edicích 2016 a nižších vyřešit pomocí FOR XML PATH a je to i vůbec nejpoužívanější způsob. V SQL Serveru 2017 dosáhneme stejného výsledku mnohem elegantnější cestou pomocí funkce STRING_AGG(), která ve všem plně nahradí FOR XML PATH.
Na následujících příkladech si ukážeme, jak na to. Naplníme si testovací tabulku jednoduchými řetězci, které spojíme dohromady pomocí FOX XML PATH. V příkladu vidíme dva možné zápisy: se specifikací datových typů a zjednodušený:
CREATE TABLE dbo.SampleTable ( Value VARCHAR(100) ) GO INSERT INTO dbo.SampleTable ( Value ) SELECT 'Value1' UNION ALL SELECT 'Value2' UNION ALL SELECT 'Value3' UNION ALL SELECT 'Value4' GO SELECT STUFF((SELECT ',' AS "text()", '''' AS "text()", Value AS "text()", '''' AS "text()" FROM dbo.SampleTable FOR XML PATH('')) , 1, 1, '') GO -- returns: 'Value1','Value2','Value3','Value4' SELECT STUFF((SELECT ',' + '''' + Value + '''' FROM dbo.SampleTable FOR XML PATH('')), 1, 1, '') GO -- returns: 'Value1','Value2','Value3','Value4'
V dalším příkladu vidíme použití stejné metody v rámci datového setu, kdy agregujeme názvy měst pro jednotlivé státy:
-- create sample tables CREATE TABLE dbo.tblCountry ( Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY, Name VARCHAR(100) NOT NULL ) CREATE TABLE dbo.tblCity ( Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY, CountryId INT NOT NULL, NAME VARCHAR(100) NOT NULL ) -- populate data ALTER TABLE dbo.tblCity ADD CONSTRAINT FK_tblCity_tblCity FOREIGN KEY (CountryId) REFERENCES dbo.tblCity (Id) INSERT INTO dbo.tblCountry VALUES ('Germany'), ('Czech Republic') INSERT INTO dbo.tblCity VALUES (1, 'Bonn'), (1, 'Berlin') INSERT INTO dbo.tblCity VALUES (2, 'Praha'), (2, 'Brno'), (2, 'Ostrava') -- review data SELECT * FROM dbo.tblCountry country INNER JOIN dbo.tblCity city ON city.CountryId = country.Id
-- put cities to inline CSV format SELECT * FROM dbo.tblCountry country CROSS APPLY (SELECT stuff((SELECT ', ' + c.Name FROM dbo.tblCity c WHERE c.CountryId = country.Id FOR XML PATH('')), 1,2,'') Cities FROM (SELECT 1 ID) a) city