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

按唯一ID按月计算累计利润的SQL实现问题求助

如何按客户ID分组计算月度累计利润?

我明白你遇到的问题了——你的全局累计变量没有在客户ID切换时重置,所以才会出现跨客户累加的情况。下面给你两种不同版本的解决方案,适配不同的MySQL环境:

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

MySQL 8.0及以上支持窗口函数,这是处理分组累计最简洁的方式,不需要手动维护变量:

先查询验证结果

SELECT 
    Year,
    Month,
    id,
    profit,
    SUM(profit) OVER (PARTITION BY id ORDER BY Year, Month) AS cumulative
FROM client;

如果要更新表中的cumulative字段

把上面的查询作为子查询,关联原表进行更新:

UPDATE client c
JOIN (
    SELECT 
        id, Year, Month,
        SUM(profit) OVER (PARTITION BY id ORDER BY Year, Month) AS new_cumulative
    FROM client
) t 
    ON c.id = t.id 
    AND c.Year = t.Year 
    AND c.Month = t.Month
SET c.cumulative = t.new_cumulative;

PARTITION BY id会把数据按客户ID分组,ORDER BY Year, Month确保每个客户内按时间顺序累计,完美符合你的需求。

方案二:兼容MySQL 5.x版本(用变量实现)

如果你的MySQL版本低于8.0,需要用变量跟踪当前客户ID,在ID变化时重置累计值:

SET @csum := 0, @prev_id := NULL;

UPDATE client
SET cumulative = (
    CASE 
        WHEN @prev_id = id THEN @csum := @csum + profit
        ELSE @csum := profit
    END
),
@prev_id := id
ORDER BY id, Year, Month;

⚠️ 这里必须加上ORDER BY id, Year, Month,确保数据先按客户分组,再按年月排序,这样变量才能正确地在每个客户内部累计,切换客户时重置@csum。

为什么你的原代码失效?

你原来的代码只初始化了@csum,没有跟踪客户ID的变化——不管当前行属于哪个客户,@csum都会一直累加,所以456客户的利润会接着123客户的累计值继续加,自然不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:49:57