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

累计余额列计算异常:SQL窗口函数语法咨询

累计余额计算异常问题

我的SQL查询中,cum_balance列用于计算累计余额,但第10行后出现异常——从该行起hour列值相同,累计值不再更新。原查询语句如下:

select
  hour,
  symbol,
  amount_usd,
  category,
  sum(amount_usd) over (
    order by
      hour asc RANGE BETWEEN UNBOUNDED PRECEDING
      AND CURRENT ROW
  ) as cum_balance
from
  combined_transfers_usd_netflow
order by
  hour

我尝试过移除RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW、添加partition by hour和group by hour,均未得到预期结果,也未报错。查询结果如下:

行号HourSYMBOLAMOUNT_USDCATEGORYCUM_BALANCE
12021-12-02 23:00:00WETH227.2795in227.2795
22021-12-03 00:00:00WETH-226.4801153out0.7993847087
32022-01-05 21:00:00WETH5123.716203in5124.515587
42022-01-18 14:00:00WETH-4466.2366out658.2789873
52022-01-19 00:00:00WETH2442.618599in3100.897586
62022-01-21 14:00:00USDC99928.68644in103029.584
72022-03-01 16:00:00UNI8545.36098in111574.945
82022-03-04 22:00:00USDC-2999.343out108575.602
92022-03-09 22:00:00USDC-5042.947675out103532.6543
102022-03-16 21:00:00USDC-4110.6579out98594.35101
112022-03-16 21:00:00UNI-3.209306045out98594.35101
122022-03-16 21:00:00UNI-16.04653022out98594.35101
132022-03-16 21:00:00UNI-16.04653022out98594.35101
142022-03-16 21:00:00UNI-16.04653022out98594.35101
152022-03-16 21:00:00UNI-6.418612089out98594.35101

问题根源

问题出在窗口框架的RANGE关键字上。当order by的列值重复时(比如第10到15行的hour完全相同),RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW会将所有hour值相同的行纳入“当前行范围”,导致这些行的累计余额都会显示为包含所有同hour行的总和,无法实现逐行累加。

你之前的尝试方向不对:移除框架声明后,部分数据库(如PostgreSQL)默认会对单个排序列使用RANGE框架,所以问题依旧;添加partition by hour会把每个hour的数据单独分区,累计值会在每个hour内重置,不符合需求;group by hour会合并同hour的行,丢失明细数据,也不是你要的结果。

正确的SQL语句

只需将RANGE替换为ROWS,强制窗口按物理行范围计算,就能实现逐行累加:

select
  hour,
  symbol,
  amount_usd,
  category,
  sum(amount_usd) over (
    order by hour asc
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) as cum_balance
from
  combined_transfers_usd_netflow
order by
  hour

如果你的数据库支持,也可以简化写法——因为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW是order by搭配ROWS框架时的默认值,所以可以省略框架声明:

select
  hour,
  symbol,
  amount_usd,
  category,
  sum(amount_usd) over (order by hour asc) as cum_balance
from
  combined_transfers_usd_netflow
order by
  hour

注意:若数据库默认框架是RANGE(如PostgreSQL),必须显式指定ROWS才能确保逐行累加。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:10:44