LØSNING
Definitionen af optimal kan variere, men her er, hvordan du sammenkæder strenge fra forskellige rækker ved hjælp af almindelig Transact SQL, som burde fungere fint i Azure.
;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
FORKLARING
Fremgangsmåden koges ned til tre trin:
-
Nummerer rækkerne med
OVER
ogPARTITION
gruppering og bestilling af dem efter behov for sammenkædningen. Resultatet erPartitioned
CTE. Vi gemmer tællinger af rækker i hver partition for at filtrere resultaterne senere. -
Brug af rekursiv CTE (
Concatenated
) gentag rækkenumrene (NameNumber
kolonne) ved at tilføjeName
værdier tilFullName
kolonne. -
Filtrer alle resultater fra, undtagen dem med det højeste
NameNumber
.
Husk, at for at gøre denne forespørgsel forudsigelig skal man definere begge grupperinger (f.eks. i dine scenarier rækker med det samme ID
er sammenkædet) og sortering (jeg gik ud fra, at du simpelthen sorterer strengen alfabetisk før sammenkædning).
Jeg har hurtigt testet løsningen på SQL Server 2012 med følgende data:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Forespørgselsresultatet:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks