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

如何在ClickHouse中维护滚动累计余额?

实现滚动累计余额的正确窗口函数用法

嘿,我懂你遇到的困扰了——本来想靠窗口函数做滚动累计,结果发现单纯拿上一行的结果来加,没法把累计值传递到下一行,越算越不对对吧?其实你要的就是滚动累计(Running Total),这事儿用窗口函数的SUM()就能轻松搞定,根本不用手动递推上一行的值!

核心思路

窗口函数里的SUM(Val) OVER()可以直接计算从第一行到当前行的累计和,它会自动把之前所有行的Val加起来,完美对应你要的“当前行Val + 上一行累计结果”的逻辑。关键是要指定按日期排序,确保累计是按时间顺序进行的。

具体示例

假设你的表叫balance_table,结构是Date DATE, Val INT,我们来写个完整的例子:

1. 测试数据(模拟你的表)

CREATE TABLE balance_table (
    Date DATE,
    Val INT
);

INSERT INTO balance_table VALUES
('2024-01-01', 100),
('2024-01-02', 50),
('2024-01-03', -30),
('2024-01-04', 200);

2. 滚动累计查询语句

SELECT
    Date,
    Val,
    SUM(Val) OVER (ORDER BY Date) AS Rolling_Balance
FROM balance_table;

3. 查询结果

DateValRolling_Balance
2024-01-01100100
2024-01-0250150
2024-01-03-30120
2024-01-04200320

你看,这个Rolling_Balance就是你要的滚动余额:每一行都是当前Val加上之前所有行的累计结果,完全符合需求!

为什么你之前的方法不行?

如果之前你用了LAG()函数,比如尝试Val + LAG(Rolling_Balance) OVER(ORDER BY Date),这会陷入死循环——因为Rolling_Balance本身就是你要计算的列,窗口函数没法引用还没计算出来的值。而SUM() OVER(ORDER BY Date)是窗口函数的原生累计逻辑,它会在内部按顺序计算从第一行到当前行的总和,不需要手动处理递推。

扩展:如果需要分组累计

要是你的表还有其他维度(比如不同用户的余额),只需要加PARTITION BY子句就行,比如:

SELECT
    User_ID,
    Date,
    Val,
    SUM(Val) OVER (PARTITION BY User_ID ORDER BY Date) AS User_Rolling_Balance
FROM user_balance_table;

这样就能按每个用户单独计算滚动余额啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 03:17:35