РЕШЕНИЕ
Определението за оптимално може да варира, но ето как да свържете низове от различни редове, като използвате обикновен Transact SQL, който трябва да работи добре в 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
ОБЯСНЕНИЕ
Подходът се свежда до три стъпки:
-
Номерирайте редовете с помощта на
OVER
иPARTITION
групирането и подреждането им според нуждите за конкатенацията. Резултатът еPartitioned
CTE. Поддържаме броя на редовете във всеки дял, за да филтрираме резултатите по-късно. -
Използване на рекурсивен CTE (
Concatenated
) итерирайте през номерата на редовете (NameNumber
колона) добавяне наName
стойности къмFullName
колона. -
Филтрирайте всички резултати, освен тези с най-висок
NameNumber
.
Моля, имайте предвид, че за да направите тази заявка предвидима, трябва да дефинирате и двете групи (например във вашия сценарий редове със същия ID
са обединени) и сортиране (предполагах, че просто сортирате низа по азбучен ред преди конкатенацията).
Бързо тествах решението на SQL Server 2012 със следните данни:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Резултатът от заявката:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks