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

MySQL双表生成累计余额台账的查询问题求解

解决MySQL收支台账的累计余额计算问题

问题说明

用UNION语句生成员工Clark的收支台账时,Balance列仅显示单行收支数值,无法实现累计余额计算。期望Balance列按规则生成:每行余额 = 前一行余额 + 当前行(Paid Amount - Received Amount)。

原查询语句:

SELECT
   a_date as `Date`,
   amount as `Paid Amount`,
   0 as `Received Amount`,
   amount - 0 as `Balance`
FROM `Table A`
WHERE name = 'Clark'
UNION
SELECT 
   b_date as `Date`,
   0 as `Paid Amount`,
   amount as `Received Amount`,
   0 - amount as `Balance`
FROM `Table B`
WHERE name = 'Clark' AND status = 'Paid' AND type = 'Loan'
ORDER BY `Date` ASC

涉及表结构及数据

Table A

a_idnamedepta_dateamount
123ClarkSales2024-01-015000
124ClarkSales2024-01-026000
125JohnSales2024-01-033500
126JohnSales2024-01-045500

Table B

b_idnamedeptb_dateamountstatustype
2001ClarkSales2024-02-051000PaidLoan
2002ClarkSales2024-02-061000UnpaidLoan
2003ClarkSales2024-02-085000PaidLoan
2004ClarkSales2024-02-091000UnpaidAdv
2005JohnSales2024-02-111000UnpaidLoan

正确SQL方案

利用MySQL窗口函数SUM() OVER()实现累计计算,先合并两张表的有效数据,再基于合并结果生成累计余额:

SELECT
    `Date`,
    `Paid Amount`,
    `Received Amount`,
    SUM(`Paid Amount` - `Received Amount`) OVER (ORDER BY `Date` ASC) AS `Balance`
FROM (
    SELECT
        a_date as `Date`,
        amount as `Paid Amount`,
        0 as `Received Amount`
    FROM `Table A`
    WHERE name = 'Clark'
    UNION ALL
    SELECT 
        b_date as `Date`,
        0 as `Paid Amount`,
        amount as `Received Amount`
    FROM `Table B`
    WHERE name = 'Clark' AND status = 'Paid' AND type = 'Loan'
) AS combined_data
ORDER BY `Date` ASC;

关键细节

  1. 用UNION ALL替代UNION:目标数据无重复,UNION ALL避免不必要的去重,提升查询性能。
  2. 窗口函数SUM() OVER(ORDER BY Date ASC):按日期升序,对每行的收支差值进行累加,直接生成累计余额。

预期查询结果

DatePaid AmountReceived AmountBalance
2024-01-01500005000
2024-01-026000011000
2024-02-050100010000
2024-02-08050005000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:43:15