按唯一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
相关产品推荐
相关产品推荐

