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

如何在MySQL中按id分组计算累计值?修正错误代码

分组计算累计Volume的SQL解决方案

嘿,我来帮你搞定这个分组累计求和的问题!先明确你的数据场景:
你有一张名为temp的数据表:

id_valdate_valvolume_val
126-Jan-18100
125-Jan-18200
124-Jan-18300
123-Jan-18150
226-Jan-18250
225-Jan-18350
224-Jan-18400
323-Jan-18500

你想要按id_val分组,按date_val降序(最新日期在前)计算累计的volume_val,目标结果如下:

id_valdate_valvolume_valcumulative_volume_val
126-Jan-18100100
125-Jan-18200300
124-Jan-18300600
123-Jan-18150750
226-Jan-18250250
225-Jan-18350600
224-Jan-184001000
323-Jan-18500500

你之前的代码问题很明确:全局变量@csum没有在每个id_val分组结束后重置,导致所有id的数值一直累加,没法实现分组内的独立累计。下面给你两种可行的改进方案:

方案一:使用窗口函数(MySQL 8.0+ 推荐)

如果你的MySQL版本是8.0及以上,窗口函数是最简洁易维护的方式,直接用SUM() OVER()语法就能实现分组累计:

SELECT 
    id_val,
    date_val,
    volume_val,
    SUM(volume_val) OVER (
        PARTITION BY id_val 
        ORDER BY date_val DESC
    ) AS cumulative_volume_val
FROM temp
ORDER BY id_val, date_val DESC;

解释:

  • PARTITION BY id_val:按id_val划分分组,每个组单独计算累计值
  • ORDER BY date_val DESC:每个组内按日期降序排序,从最新日期开始依次累加

方案二:使用变量兼容低版本MySQL

如果你的MySQL版本低于8.0,就需要用变量来实现,核心是在id_val变化时重置累计值:

SELECT 
    id_val,
    date_val,
    volume_val,
    @csum := CASE 
        WHEN @prev_id = id_val THEN @csum + volume_val
        ELSE volume_val
    END AS cumulative_volume_val,
    @prev_id := id_val -- 记录当前id,用于下一行的分组判断
FROM temp,
(SELECT @csum := 0, @prev_id := NULL) AS init_vars
ORDER BY id_val, date_val DESC;

解释:

  • 初始化两个变量:@csum存储当前累计值,@prev_id存储上一行的id_val
  • 每一行判断当前id_val是否和上一行相同:
    • 相同则继续累加volume_val到@csum
    • 不同则把@csum重置为当前行的volume_val
  • 必须按id_val和date_val DESC排序,保证分组和累加顺序的正确性

这样就能得到你想要的分组累计结果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:49:04