Oracle HR模式下用窗口子句计算各部门Top3员工薪资总和
解决Oracle HR模式中各部门Top3员工薪资求和问题
问题分析
你当前的查询使用了带排序和范围的窗口求和,返回的是累积薪资和(每行对应从当前员工到后续员工的薪资总和),因此每个部门会生成多行冗余结果。要实现每个部门仅一行的Top3薪资总和,需调整窗口函数用法,确保计算的是部门内所有符合条件员工的薪资总额,再通过去重或聚合得到唯一行。
方法一:DISTINCT + 无排序窗口求和(简洁版)
先筛选出各部门薪资Top3的员工,再用窗口函数计算部门内这些员工的薪资总和,最后通过DISTINCT保留每个部门的唯一结果:
SELECT DISTINCT department_id, SUM(salary) OVER (PARTITION BY department_id) AS total_top3_salary FROM ( SELECT department_id, salary, ROW_NUMBER() OVER(PARTITION BY department_id ORDER BY salary DESC) AS result FROM employees ) WHERE result <= 3;
方法二:聚合函数去重(替代方案)
如果不想使用DISTINCT,可以在外层对部门分组,取求和结果的最大值(同一部门的求和结果完全相同):
SELECT department_id, MAX(total_sal) AS total_top3_salary FROM ( SELECT department_id, SUM(salary) OVER (PARTITION BY department_id) AS total_sal FROM ( SELECT department_id, salary, ROW_NUMBER() OVER(PARTITION BY department_id ORDER BY salary DESC) AS result FROM employees ) WHERE result <= 3 ) GROUP BY department_id;
关键调整说明
- 移除窗口函数中的
ORDER BY salary和ROWS BETWEEN...子句:这些子句会让窗口函数计算累积和,而非整个部门分区的总和。我们需要的是部门内所有Top3员工的薪资总额,因此只需按department_id分区即可。 - 子查询仅保留必要列:无需返回员工ID、姓名等无关列,减少数据处理量。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

