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

如何在聚合查询中包含最早过账交易的原始金额?

如何在冲销交易聚合查询中添加每组最早过账日期的原始金额?

你当前的查询已经能精准筛选出金额总和为0的冲销交易组了,现在想要给结果加上每组里过账日期(PostedDate)最早的那笔交易的原始金额,对吧?结合你给出的示例数据和预期结果,我给你两种可行的解决方案:

方案一:用ROW_NUMBER()标记最早记录

这种方法兼容性较强,几乎所有支持窗口函数的数据库都能使用:

WITH RankedTransactions AS (
    SELECT 
        [Account],
        [Voucher],
        [DocumentDate],
        [Amount],
        -- 按分组字段划分组,每组内按PostedDate升序排号,最早的记录标记为1
        ROW_NUMBER() OVER (PARTITION BY [Account], [Voucher], [DocumentDate] ORDER BY [PostedDate] ASC) AS rn
    FROM MyTable
    WHERE [Account] = 'abc'
)
SELECT 
    rt.[Account],
    rt.[Voucher],
    rt.[DocumentDate],
    -- 提取每组中标记为1的记录的金额作为原始金额
    MAX(CASE WHEN rn = 1 THEN rt.[Amount] END) AS OriginalAmount,
    SUM(rt.[Amount]) AS [Sum(Amount)],
    COUNT(*) AS Records
FROM RankedTransactions rt
GROUP BY rt.[Account], rt.[Voucher], rt.[DocumentDate]
HAVING SUM(rt.[Amount]) = 0;

逻辑说明:

  1. 先用CTERankedTransactions给每条记录按Account、Voucher、DocumentDate分组,组内按PostedDate从小到大排序,最早的记录会被标记为rn=1;
  2. 后续聚合查询中,通过MAX(CASE WHEN rn=1 THEN Amount END)提取每组最早交易的金额(因为每组只有一条rn=1的记录,用MIN也能达到同样效果);
  3. 保留你原有的SUM(Amount)计算,新增COUNT(*)统计每组的记录数,最后用HAVING过滤出总和为0的冲销组。

用你的示例数据测试的话,会完美输出预期结果:OriginalAmount=100.00,Sum(Amount)=0.00,Records=2。

方案二:用FIRST_VALUE()直接获取最早金额

如果你的数据库支持FIRST_VALUE函数(比如SQL Server 2012+、PostgreSQL、MySQL 8.0+等),这种写法会更直观:

WITH GroupedWithFirstAmount AS (
    SELECT 
        [Account],
        [Voucher],
        [DocumentDate],
        [Amount],
        -- 直接获取每组内PostedDate最早的交易金额
        FIRST_VALUE([Amount]) OVER (PARTITION BY [Account], [Voucher], [DocumentDate] ORDER BY [PostedDate] ASC) AS OriginalAmount
    FROM MyTable
    WHERE [Account] = 'abc'
)
SELECT DISTINCT
    [Account],
    [Voucher],
    [DocumentDate],
    OriginalAmount,
    SUM([Amount]) OVER (PARTITION BY [Account], [Voucher], [DocumentDate]) AS [Sum(Amount)],
    COUNT(*) OVER (PARTITION BY [Account], [Voucher], [DocumentDate]) AS Records
FROM GroupedWithFirstAmount
WHERE SUM([Amount]) OVER (PARTITION BY [Account], [Voucher], [DocumentDate]) = 0;

逻辑说明:

  1. 用FIRST_VALUE窗口函数直接在CTE中获取每组最早过账交易的金额;
  2. 之后用窗口聚合函数SUM()和COUNT()计算每组的总金额和记录数,最后通过DISTINCT去重并过滤出总和为0的组。

两种方案都能满足你的需求,你可以根据自己使用的数据库类型和个人习惯选择。

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:31:04