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

如何用LAG函数计算借贷方滚动余额?附会计表数据及错误尝试

嘿,我来帮你搞定这个滚动余额计算的问题~

你之前用LAG函数没成功,是因为LAG只能取前一行的特定值,没办法实现累计求和的逻辑——而滚动余额本质是按顺序累加所有借方(DR)、累加所有贷方(CR),再用累计借方减累计贷方得到的结果。

正确的解决思路

我们需要用窗口函数SUM() OVER()来计算累计DR和累计CR,然后基于这两个累计值算出余额,最后再根据余额的正负调整显示格式(比如正数加dr,负数加括号和cr)。

完整SQL代码(Oracle为例)

SELECT 
    id,
    edate,
    discription,
    dr,
    cr,
    CASE 
        WHEN balance_num > 0 THEN TO_CHAR(balance_num) || 'dr'
        WHEN balance_num < 0 THEN '(' || TO_CHAR(ABS(balance_num)) || ')cr'
        ELSE '0'
    END AS BALANCE
FROM (
    -- 先计算累计余额的数值
    SELECT 
        id,
        edate,
        discription,
        dr,
        cr,
        SUM(dr) OVER(ORDER BY id) - SUM(cr) OVER(ORDER BY id) AS balance_num
    FROM accounting
) t
ORDER BY id;

代码解释

  1. 子查询里的SUM(dr) OVER(ORDER BY id)会按ID顺序累加所有DR值,SUM(cr) OVER(ORDER BY id)同理累加CR值,两者相减就是当前行的滚动余额数值。
  2. 外层用CASE语句处理显示格式:
    • 余额为正:显示数值加dr
    • 余额为负:显示括号包裹绝对值加cr
    • 余额为0:直接显示0

验证结果

运行这段代码后,你会得到完全符合预期的输出:

IDEDATEDISCRIPTIONDRCRBALANCE
119-JAN-19cash in100001000dr
219-JAN-19cash out0200800dr
319-JAN-19cash in50001300dr
419-JAN-19cash out02001100dr
519-JAN-19cash out0200900dr
619-JAN-19cash out01800(900)cr

如果你用的是其他数据库(比如MySQL),只需要把字符串拼接的||换成CONCAT(),TO_CHAR()换成CAST(balance_num AS CHAR)就可以啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:44:05