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

计算付款后当前余额SQL查询异常求助:Balance字段无法正确取值

计算付款后的当前余额问题

数据表结构与数据

表AG的记录如下:

buysell payment_date    balance     amount_paid 
175325  2023-07-01      1000.00     NULL             
175325  2023-07-02      0.00        500.00            
175325  2023-07-03      0.00        400.00            
175325  2023-07-04      0.00        100.00    

期望结果

需要得到付款后的当前余额,结果格式如下:

payment_date    balance  amount_paid    current_balance
2023-07-01      1000.00  NULL           1000.00
2023-07-02      0.00     500.00         500.00
2023-07-03      0.00     400.00         100.00
2023-07-04      0.00     100.00         0.00   

我的SQL查询语句

我尝试用CTE计算累计付款,但结果不正确:

;with ctec as
( 
    select payment_date, balance, amount_paid,
    sum(amount_paid) over (order by payment_date) as running_total
    from  AG
) 

select  payment_date, balance, amount_paid, 
        balance - coalesce(running_total, 0) as current_balance
from
    ctec
    group by  payment_date, balance, amount_paid, running_total
order by
    payment_date  

问题说明

上述查询返回结果错误,但把balance - coalesce(running_total, 0)改成1000 - coalesce(running_total, 0)就能得到正确结果。由于无法提前知晓初始余额的固定数值,必须使用表中的balance字段,求解决办法。


解决方案

问题根源:除了第一行记录,其余行的balance值都是0,直接用当前行的balance减累计付款额,自然会得到错误结果。正确的做法是获取同一buysell分组下的初始余额(即最早日期的balance值),再减去累计付款额。

修改后的SQL(两种写法任选其一)

写法1:用MAX()窗口函数获取初始余额

;with ctec as
( 
    select 
        payment_date, 
        balance, 
        amount_paid,
        -- 按buysell分组计算累计付款
        sum(amount_paid) over (partition by buysell order by payment_date) as running_total,
        -- 取分组内最大的balance(即初始余额,其余为0)
        max(balance) over (partition by buysell) as initial_balance
    from  AG
) 

select  
    payment_date, 
    balance, 
    amount_paid, 
    initial_balance - coalesce(running_total, 0) as current_balance
from ctec
order by payment_date  

写法2:用FIRST_VALUE()窗口函数获取初始余额

;with ctec as
( 
    select 
        payment_date, 
        balance, 
        amount_paid,
        sum(amount_paid) over (partition by buysell order by payment_date) as running_total,
        -- 取分组内最早日期的balance值作为初始余额
        first_value(balance) over (partition by buysell order by payment_date) as initial_balance
    from  AG
) 

select  
    payment_date, 
    balance, 
    amount_paid, 
    initial_balance - coalesce(running_total, 0) as current_balance
from ctec
order by payment_date  

说明

  • 增加partition by buysell确保累计计算和初始余额获取都在同一交易分组内进行,避免不同buysell的数据互相干扰。
  • first_value(balance)会直接取分组内排序后的第一条记录的balance,也就是初始余额;max(balance)则利用初始余额是分组内唯一非0值的特性获取初始余额,两种方式都能得到正确结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:28:14