SOLUTION
的定义optimal可能会有所不同,但以下是如何使用常规 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
and PARTITION
根据串联的需要对它们进行分组和排序。结果是Partitioned
热膨胀系数。我们保留每个分区中的行数以便稍后过滤结果。
使用递归 CTE (Concatenated
) 迭代行号 (NameNumber
列)添加Name
价值观FullName
column.
过滤掉除了最高的结果之外的所有结果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