按员工分组实现累计休假时长累加的SQL技术问题
解决员工累计休假天数计算的分组问题
嘿,我完全懂你现在的困扰——之前的查询没按员工分组,导致把所有员工的休假天数都混在一起累加了,结果肯定不对对吧?别慌,咱们来搞定这个问题。
首先先把你的表结构和测试数据补全一下(方便演示):
CREATE TABLE SampleLeave ( ID Numeric, EmpCode Numeric, NoOfLeaves Numeric ); INSERT INTO SampleLeave VALUES (1, 12, 2); INSERT INTO SampleLeave VALUES (2, 12, 3); INSERT INTO SampleLeave VALUES (3, 13, 1); INSERT INTO SampleLeave VALUES (4, 13, 4);
你的核心问题是没有按员工代码(EmpCode)进行分组计算,所以累计的是所有员工的总休假天数,而不是单个员工的。现在用窗口函数就能轻松解决,这也是最高效的方式:
SELECT ID, EmpCode, NoOfLeaves, SUM(NoOfLeaves) OVER (PARTITION BY EmpCode ORDER BY ID) AS CumulativeLeaves FROM SampleLeave;
咱们来拆解一下这段SQL的关键部分:
PARTITION BY EmpCode:把整个数据集按员工代码拆分成独立的小组,每个员工的计算互不干扰ORDER BY ID:确保累计是按照休假记录的先后顺序来的(如果你的表有专门的休假日期字段,比如LeaveDate,用它排序会更准确,这里假设ID是自增的,代表休假的先后顺序)SUM(NoOfLeaves) OVER (...):对每个员工分组内的行,从第一行到当前行逐步累加休假天数,得到每次休假后的累计值
执行这个查询后,你会得到这样的结果:
| ID | EmpCode | NoOfLeaves | CumulativeLeaves |
|---|---|---|---|
| 1 | 12 | 2 | 2 |
| 2 | 12 | 3 | 5 |
| 3 | 13 | 1 | 1 |
| 4 | 13 | 4 | 5 |
如果你的SQL版本比较老(比如MySQL 5.7及以前)不支持窗口函数,那可以用关联子查询来实现同样的效果:
SELECT s1.ID, s1.EmpCode, s1.NoOfLeaves, (SELECT SUM(s2.NoOfLeaves) FROM SampleLeave s2 WHERE s2.EmpCode = s1.EmpCode AND s2.ID <= s1.ID) AS CumulativeLeaves FROM SampleLeave s1 ORDER BY s1.EmpCode, s1.ID;
这个子查询的逻辑是:对每一行记录,找到同一个员工且ID不大于当前行的所有休假记录,求和得到累计天数。不过要注意,这种方式在数据量大的时候性能不如窗口函数,所以优先用窗口函数方案。
内容的提问来源于stack exchange,提问作者Doonie Darkoo
相关产品推荐
相关产品推荐

