You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL Server中同一账号(PK)的多行交易数据合并为单行?

嘿,这个场景我经常碰到!在SQL Server里,把同一账号的多行交易数据合并到一行,主要有两种常用方案,看你用的是哪个版本的SQL Server:

方案1:使用 STRING_AGG(SQL Server 2017+ 推荐)

这个函数是SQL Server 2017及以后版本引入的,专门用来聚合字符串,语法简洁到爆。你可以按账号分组,然后把交易值和交易日期分别(或者一起)拼接成字符串:

示例代码:

SELECT 
    Acc#,
    -- 拼接交易值,按交易日期倒序排列
    STRING_AGG(TransactionValue, ', ') WITHIN GROUP (ORDER BY TransactionDate DESC) AS CombinedTransactionValues,
    -- 拼接交易日期,同样按日期排序
    STRING_AGG(CONVERT(VARCHAR, TransactionDate, 105), ', ') WITHIN GROUP (ORDER BY TransactionDate DESC) AS CombinedTransactionDates,
    -- 也可以把值和日期配对拼接,比如 "R2500 (25-04-2018), R5235 (23-04-2018)"
    STRING_AGG(CONCAT(TransactionValue, ' (', CONVERT(VARCHAR, TransactionDate, 105), ')'), ', ') WITHIN GROUP (ORDER BY TransactionDate DESC) AS CombinedTransactions
FROM YourTableName
GROUP BY Acc#;

解释一下:

  • STRING_AGG(要聚合的字段, 分隔符) 会把同一组的字段值用分隔符连起来
  • WITHIN GROUP (ORDER BY ...) 可以指定拼接的顺序,比如按交易日期从新到旧排
  • CONVERT(VARCHAR, TransactionDate, 105) 是把日期转成dd-mm-yyyy的格式,和你示例里的一致

运行你给的示例数据,结果会是:

Acc#       CombinedTransactionValues  CombinedTransactionDates  CombinedTransactions
---------- ------------------------- ------------------------- -------------------------------
123658421  R2500, R5235              25-04-2018, 23-04-2018    R2500 (25-04-2018), R5235 (23-04-2018)
方案2:使用 FOR XML PATH(兼容SQL Server 2016及更早版本)

如果你的SQL Server版本比较旧,没法用STRING_AGG,那就用这个经典的XML拼接方法:

示例代码:

SELECT 
    DISTINCT Acc#,
    -- 拼接交易值
    STUFF((
        SELECT ', ' + TransactionValue
        FROM YourTableName t2
        WHERE t2.Acc# = t1.Acc#
        ORDER BY t2.TransactionDate DESC
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS CombinedTransactionValues,
    -- 拼接交易日期
    STUFF((
        SELECT ', ' + CONVERT(VARCHAR, TransactionDate, 105)
        FROM YourTableName t2
        WHERE t2.Acc# = t1.Acc#
        ORDER BY t2.TransactionDate DESC
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS CombinedTransactionDates,
    -- 配对拼接值和日期
    STUFF((
        SELECT ', ' + CONCAT(TransactionValue, ' (', CONVERT(VARCHAR, TransactionDate, 105), ')')
        FROM YourTableName t2
        WHERE t2.Acc# = t1.Acc#
        ORDER BY t2.TransactionDate DESC
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS CombinedTransactions
FROM YourTableName t1;

解释一下:

  • 子查询里用FOR XML PATH('')会把查询结果拼成一个XML字符串(没有标签)
  • TYPE参数确保特殊字符被正确处理(比如如果交易值里有&、<这些符号不会乱码)
  • STUFF(..., 1, 2, '') 是去掉字符串开头的, (因为子查询开头会多一个分隔符)

这个方法的结果和方案1完全一样,只是写法繁琐一点,但胜在兼容性好。

额外说明

如果你不是要把多个值拼成字符串,而是要把不同日期的交易值拆成单独的列(比如第一笔交易、第二笔交易各占一列),那你需要用PIVOT或者动态SQL来实现,但从你的描述来看,应该是要合并成同一行的字符串列,上面两种方法就足够了。

记得把代码里的YourTableName换成你实际的表名哦!

内容的提问来源于stack exchange,提问作者Z.L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:24:09