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

SQL实现累计余额计算:当前Balance累加上一行Balance

解决逐行累计余额的SQL实现问题

你的现有查询问题出在使用了GROUP BY——这是做分组聚合,而不是你需要的逐行累加计算,所以自然得不到预期的累计余额结果。下面给你一个符合需求的正确实现方案:

核心思路

要实现「当前行Balance + 上一行Balance」的累计效果,我们需要:

  1. 先正确计算每行的单独Balance(处理NULL值,确保计算逻辑准确);
  2. 使用窗口函数SUM() OVER()来实现逐行累加的运行总计(Running Total);
  3. 给每行指定明确的顺序(SQL表本身是无序的,必须保证累加顺序和你预期的一致)。

完整SQL代码

declare @tab table(Debit int,Credit int)
insert into @tab select 1000 , NULL union all select 2200 , NULL union all select NULL , 3000 union all select 1500 , 1500

-- 生成带累计余额的结果集
SELECT 
    Debit,
    Credit,
    -- 计算当前行的单笔余额:Debit为收入,Credit为支出,NULL视为0
    ISNULL(Debit, 0) - ISNULL(Credit, 0) AS Balance,
    -- 逐行累加的累计余额:从第一行到当前行的Balance总和
    SUM(ISNULL(Debit, 0) - ISNULL(Credit, 0)) OVER (ORDER BY RowNum) AS CumulativeBalance
FROM (
    -- 先给每行分配行号,确保累加顺序和插入顺序一致(如果有其他排序字段可替换这里的ORDER BY)
    SELECT 
        Debit,
        Credit,
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum
    FROM @tab
) AS t

代码解释

  • 行号分配:内层查询用ROW_NUMBER()给每行加唯一行号,ORDER BY (SELECT NULL)在SQL Server中会遵循数据插入的顺序排序;如果你有业务上的排序字段(比如交易日期),把这里替换成对应的字段即可。
  • 单笔Balance计算:用ISNULL(Debit, 0) - ISNULL(Credit, 0)处理NULL值,把空值视为0,符合常规的财务逻辑(收入减支出)。如果你的Balance逻辑是原查询里的「有Credit取Credit,否则取Debit」,可以把这部分改成COALESCE(Credit, Debit),但注意这可能不符合常规的收支计算逻辑。
  • 累计余额计算:SUM(...) OVER (ORDER BY RowNum)是窗口函数,它会计算从第一行到当前行的Balance总和,完美实现你要的逐行累加效果。

执行结果示例

DebitCreditBalanceCumulativeBalance
1000NULL10001000
2200NULL22003200
NULL3000-3000200
150015000200

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:54:52