LÖSNING
Definitionen av optimal kan variera, men så här sammanfogar du strängar från olika rader med vanlig Transact SQL, vilket borde fungera bra 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
FÖRKLARING
Tillvägagångssättet kokar ner till tre steg:
-
Numrera raderna med
OVER
ochPARTITION
gruppera och beställa dem efter behov för sammanlänkningen. Resultatet ärPartitioned
CTE. Vi behåller antalet rader i varje partition för att filtrera resultaten senare. -
Använder rekursiv CTE (
Concatenated
) iterera genom radnumren (NameNumber
kolumn) lägga tillName
värden tillFullName
kolumn. -
Filtrera bort alla resultat utom de med högst
NameNumber
.
Tänk på att för att göra denna fråga förutsägbar måste man definiera båda grupperingarna (till exempel i dina scenariorader med samma ID
är sammanlänkade) och sortering (jag antog att du helt enkelt sorterar strängen alfabetiskt före sammanlänkning).
Jag har snabbt testat lösningen på SQL Server 2012 med följande data:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Frågeresultatet:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks