GIẢI PHÁP
Định nghĩa của tối ưu có thể khác nhau, nhưng đây là cách nối các chuỗi từ các hàng khác nhau bằng cách sử dụng Transact SQL thông thường, sẽ hoạt động tốt trong 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
GIẢI THÍCH
Phương pháp này có ba bước sau:
-
Đánh số các hàng bằng
OVER
vàPARTITION
nhóm và sắp xếp chúng khi cần thiết cho quá trình nối. Kết quả làPartitioned
CTE. Chúng tôi giữ số lượng hàng trong mỗi phân vùng để lọc kết quả sau này. -
Sử dụng CTE đệ quy (
Concatenated
) lặp qua các số hàng (NameNumber
cột) thêmName
các giá trị thànhFullName
cột. -
Lọc ra tất cả các kết quả trừ những kết quả có
NameNumber
cao nhất .
Xin lưu ý rằng để làm cho truy vấn này có thể dự đoán được, người ta phải xác định cả hai nhóm (ví dụ:trong các hàng kịch bản của bạn có cùng một ID
được nối) và sắp xếp (tôi cho rằng bạn chỉ cần sắp xếp chuỗi theo thứ tự bảng chữ cái trước khi nối).
Tôi đã nhanh chóng thử nghiệm giải pháp trên SQL Server 2012 với dữ liệu sau:
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
Kết quả truy vấn:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks