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
OVER
undPARTITION
Gruppieren und Ordnen sie nach Bedarf für die Verkettung. Das Ergebnis istPartitioned
CTE. Wir zählen die Zeilen in jeder Partition, um die Ergebnisse später zu filtern. -
Mit rekursivem CTE (
Concatenated
) durch die Zeilennummern iterieren (NameNumber
Spalte) Hinzufügen vonName
Werte zuFullName
Spalte. -
Alle Ergebnisse außer denen mit der höchsten
NameNumber
herausfiltern .
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