SQL分组查询错误排查:部门高薪资员工数统计问题
问题拆解与解决方案
先聊聊原SQL的问题出在哪,再给你两种实用的实现思路~
错误原因分析
原语句完全搞反了需求的逻辑顺序:
- 需求的核心是先找总员工数超过5人的部门,再统计这些部门里薪资超$40000的员工数量
- 但原SQL里
WHERE dnumber = dno AND salary > 40000先把所有高薪员工筛选出来了,之后的GROUP BY dname和HAVING COUNT(*) >5,本质是在统计"高薪员工数超过5人"的部门,完全忽略了"部门总员工数>5"这个前提条件。 - 举个直观的例子:如果一个部门有10个员工,但只有3个高薪的,原语句会直接跳过这个部门,但实际上它是符合需求的,应该被列出来,并且统计数是3。
正确实现方案
方法1:子查询先筛选符合总人数要求的部门
先通过子查询找出所有总员工数超过5的部门编号,再关联员工表统计这些部门里的高薪人数:
SELECT d.dname, COUNT(e.SSN) AS high_salary_employee_count FROM Department d INNER JOIN Employee e ON d.Dnumber = e.DNO WHERE d.Dnumber IN ( -- 先筛选出总员工数>5的部门编号 SELECT DNO FROM Employee GROUP BY DNO HAVING COUNT(*) > 5 ) AND e.salary > 40000 GROUP BY d.dname;
方法2:一次聚合完成统计(更高效)
用条件聚合的方式,在一次分组中同时统计部门总人数和高薪人数,再用HAVING过滤总人数符合要求的部门,这种方法只需要一次表关联,性能更优:
SELECT d.dname, -- 用CASE判断薪资是否达标,符合记1否则记0,求和得到高薪员工数 SUM(CASE WHEN e.salary > 40000 THEN 1 ELSE 0 END) AS high_salary_employee_count FROM Department d INNER JOIN Employee e ON d.Dnumber = e.DNO GROUP BY d.dname, d.Dnumber -- 加上部门编号避免同名部门混淆 HAVING COUNT(*) > 5; -- 这里的COUNT(*)是部门总员工数,用来过滤符合要求的部门
两种方法都能满足需求,方法2还能处理部门名称重复的极端情况,推荐优先使用。
内容的提问来源于stack exchange,提问作者MistaOS
相关产品推荐
相关产品推荐

