ŘEŠENÍ
Definice optimálního se může lišit, ale zde je návod, jak zřetězit řetězce z různých řádků pomocí běžného Transact SQL, což by mělo v Azure fungovat dobře.
;WITH Partitioned AS
(
SELECT
ID,
Name,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Name) AS NameNumber,
COUNT(*) OVER (PARTITION BY ID) AS NameCount
FROM dbo.SourceTable
),
Concatenated AS
(
SELECT
ID,
CAST(Name AS nvarchar) AS FullName,
Name,
NameNumber,
NameCount
FROM Partitioned
WHERE NameNumber = 1
UNION ALL
SELECT
P.ID,
CAST(C.FullName + ', ' + P.Name AS nvarchar),
P.Name,
P.NameNumber,
P.NameCount
FROM Partitioned AS P
INNER JOIN Concatenated AS C
ON P.ID = C.ID
AND P.NameNumber = C.NameNumber + 1
)
SELECT
ID,
FullName
FROM Concatenated
WHERE NameNumber = NameCount
VYSVĚTLENÍ
Tento přístup se scvrkává na tři kroky:
-
Očíslujte řádky pomocí
OVER
aPARTITION
seskupování a řazení podle potřeby pro zřetězení. Výsledkem jePartitioned
CTE. Uchováváme počty řádků v každém oddílu, abychom mohli výsledky filtrovat později. -
Pomocí rekurzivního CTE (
Concatenated
) iterujte čísla řádků (NameNumber
sloupec) přidánímName
hodnoty naFullName
sloupec. -
Odfiltrujte všechny výsledky kromě těch s nejvyšší hodnotou
NameNumber
.
Mějte prosím na paměti, že aby byl tento dotaz předvídatelný, musíte definovat obě seskupení (například v řádcích vašeho scénáře se stejným ID
jsou zřetězeny) a řazení (předpokládal jsem, že před zřetězením jednoduše seřadíte řetězec podle abecedy).
Rychle jsem otestoval řešení na SQL Server 2012 s následujícími údaji:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Výsledek dotazu:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks