基于manager_id分组实现薪资连续累计生成Salary_Sum列的方法
同Manager_id维度的薪资逐行累计求和实现
通用主流方案(支持窗口函数的SQL版本:MySQL8.0+、PostgreSQL、SQL Server、Oracle等)
直接利用窗口函数的分组累计能力实现,无需复杂关联查询:
SELECT Manager_id, Salary, SUM(Salary) OVER ( -- 按Manager_id拆分独立计算分组 PARTITION BY Manager_id -- 必须指定组内的行排序规则,否则SUM()会直接返回整个分组的总薪资 ORDER BY 你的累计排序字段(如发薪日、记录录入时间) -- 行范围固定为:从组内第一行到当前行,实现逐行累加 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS Salary_Sum FROM your_salary_data_table
对应示例数据的输出结果
| Manager_id | Salary | Salary_Sum |
|---|---|---|
| 100 | 1200 | 1200 |
| 100 | 1400 | 2600 |
| 100 | 1600 | 4200 |
| 103 | 1800 | 1800 |
| 104 | 1900 | 1900 |
老版本兼容方案(不支持窗口函数的SQL环境,如MySQL 5.7及更早版本)
通过会话变量逐行计算累计值,核心是要保证数据排序后再触发变量计算:
SELECT inner_t.Manager_id, inner_t.Salary, -- 同组就累加累计值,切换到新组就把累计值重置为当前行薪资 @running_total := IF(@last_mgr = inner_t.Manager_id, @running_total + inner_t.Salary, inner_t.Salary) AS Salary_Sum, @last_mgr := inner_t.Manager_id FROM ( -- 内层先把数据按Manager_id、实际累计排序规则排好 SELECT Manager_id, Salary FROM your_salary_data_table ORDER BY Manager_id, 你的累计排序字段 ) inner_t, -- 初始化会话变量 (SELECT @last_mgr := NULL, @running_total := 0) init_var
关键注意事项
- 累计结果完全依赖行顺序:不指定明确排序规则时,数据库返回的行序不受保障,累计值可能和预期对不上
- 以上计算的累计列是查询时动态生成的,如需把结果固化到原表中,可以用
CREATE TABLE new_table AS + 上述查询语句生成新表,再根据需求关联回原表更新对应列
内容的提问来源于stack exchange,提问作者Prabhat Bhatt
相关产品推荐
相关产品推荐

