首页 >数据库 >mysql教程 >如何在不使用 FOR XML 或 CLR 函数的情况下有效连接 SQL Server 中多行的字符串?

如何在不使用 FOR XML 或 CLR 函数的情况下有效连接 SQL Server 中多行的字符串?

DDD
DDD原创
2025-01-20 09:12:11986浏览

How Can I Efficiently Concatenate Strings from Multiple Rows in SQL Server Without Using FOR XML or CLR Functions?

SQL Server字符串连接方法

问题描述:

您需要将多行中的字符串聚合到单行中。COALESCE和FOR XML无法满足您的需求,并且Azure不支持CLR定义的聚合函数。您需要寻找最佳的替代方案。

解决方案:

使用标准Transact SQL,您可以通过以下步骤高效地连接字符串:

  1. 编号行:基于分组标准对数据进行分区,并在每个分区内分配行号。
  2. 递归连接:创建一个递归CTE,根据行号迭代连接字符串。
  3. 筛选结果:仅选择具有最高行号的结果,确保完整的连接。

说明:

此方法使用三个CTE:

  • Partitioned:为每个分区内的行分配行号。
  • Concatenated:递归构建连接的字符串。
  • Final Result:筛选连接的行,仅包含完整的结果。

要使用此解决方案,您必须指定分组和排序标准。例如,在您的情况下,具有相同ID的行按字母顺序连接和排序。

示例:

考虑以下数据:

<code>ID  Name
-- --
1   Matt
1   Rocks
2   Stylus
3   Foo
3   Bar
3   Baz</code>

查询及其输出如下:

<code class="language-sql">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(max)) AS FullName, 
        Name, 
        NameNumber, 
        NameCount 
    FROM Partitioned 
    WHERE NameNumber = 1

    UNION ALL

    SELECT 
        P.ID, 
        CAST(C.FullName + ', ' + P.Name AS nvarchar(max)), 
        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;</code>
<code>ID  FullName
-- ------------------------------
2   Stylus
3   Bar, Baz, Foo
1   Matt, Rocks</code>

改进说明:nvarchar类型改为nvarchar(max),以支持更长的字符串连接结果。 这避免了潜在的字符串长度溢出错误。

以上是如何在不使用 FOR XML 或 CLR 函数的情况下有效连接 SQL Server 中多行的字符串?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn