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

