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

SQL如何逐行计算累计值:计算Account_ID 1的账户交易余额

SQL实现账户逐行累计余额计算方法

这类逐行计算交易后账户余额的需求,在SQL中可以非常方便的实现,主流方案是使用窗口函数,低版本数据库也可以用子查询实现。

方案1:窗口函数(推荐,性能好,语法简洁)

窗口函数是SQL标准中专门用于这类跨行计算的语法,支持MySQL 8.0+、PostgreSQL、SQL Server、Oracle、Hive、Spark SQL等几乎所有主流新版数据库。

假设你的交易表名为transaction_records,核心字段如下:

  • account_id:账户ID
  • transaction_time:交易发生时间,用于确定交易顺序
  • transaction_amount:交易金额,支出存为负数、收入存为正数

针对Account_ID为1、初始余额为500的计算代码如下:

SELECT 
  account_id,
  transaction_time,
  transaction_amount,
  -- 初始余额 + 累计到当前行的交易金额总和
  500 + SUM(transaction_amount) OVER (
    PARTITION BY account_id 
    ORDER BY transaction_time ASC
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS account_balance
FROM transaction_records
WHERE account_id = 1
ORDER BY transaction_time ASC;

语法说明

  • PARTITION BY account_id:按账户ID分区,每个账户的累计计算独立
  • ORDER BY transaction_time ASC:按交易时间排序,保证累计顺序和交易发生顺序一致
  • ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:指定求和范围为当前分区的第一行到当前行,实现逐行累加的效果

如果你的表中是单独存储收支类型和正数金额,也可以通过CASE语句转换后计算:

SELECT 
  account_id,
  transaction_time,
  amount,
  500 + SUM(CASE WHEN is_income = 1 THEN amount ELSE -amount END) OVER (
    PARTITION BY account_id 
    ORDER BY transaction_time ASC
  ) AS account_balance
FROM transaction_records
WHERE account_id = 1
ORDER BY transaction_time ASC;

方案2:关联子查询(兼容低版本不支持窗口函数的数据库)

如果你使用的是不支持窗口函数的低版本数据库,比如MySQL 5.x,可以用关联子查询实现,缺点是数据量大的时候性能较差:

SELECT 
  t1.account_id,
  t1.transaction_time,
  t1.transaction_amount,
  500 + (
    SELECT SUM(t2.transaction_amount)
    FROM transaction_records t2
    WHERE t2.account_id = t1.account_id 
    AND t2.transaction_time <= t1.transaction_time
  ) AS account_balance
FROM transaction_records t1
WHERE t1.account_id = 1
ORDER BY t1.transaction_time ASC;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:15:05