LÖSUNG
Die Definition von optimal kann variieren, aber hier erfahren Sie, wie Sie Zeichenfolgen aus verschiedenen Zeilen mit normalem Transact SQL verketten, was in Azure problemlos funktionieren sollte.
;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
ERKLÄRUNG
Der Ansatz läuft auf drei Schritte hinaus:
-
Nummerieren Sie die Zeilen mit
OVERundPARTITIONGruppieren und Ordnen sie nach Bedarf für die Verkettung. Das Ergebnis istPartitionedCTE. Wir zählen die Zeilen in jeder Partition, um die Ergebnisse später zu filtern. -
Mit rekursivem CTE (
Concatenated) durch die Zeilennummern iterieren (NameNumberSpalte) Hinzufügen vonNameWerte zuFullNameSpalte. -
Alle Ergebnisse außer denen mit der höchsten
NameNumberherausfiltern .
Bitte beachten Sie, dass Sie, um diese Abfrage vorhersagbar zu machen, beide Gruppierungen definieren müssen (z. B. in Ihrem Szenario Zeilen mit derselben ID verkettet werden) und Sortierung (ich bin davon ausgegangen, dass Sie die Zeichenfolge vor der Verkettung einfach alphabetisch sortieren).
Ich habe die Lösung schnell auf SQL Server 2012 mit den folgenden Daten getestet:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Das Abfrageergebnis:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks