解决方案
最佳的定义可能会有所不同,但这里是如何使用常规 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