SQL入门求助:统计每位员工下属数量的最优SQL写法
解决MySQL自连接统计员工下属数量的计数误差问题
问题场景
需要统计员工表中每位员工的下属数量,表结构及数据如下:
| emp_id | super_id |
|---|---|
| 100 | NULL |
| 101 | 100 |
| 102 | 100 |
| 103 | 102 |
| 104 | 102 |
| 105 | 102 |
| 106 | 100 |
| 107 | 106 |
| 108 | 106 |
错误原因分析
- 初始语句问题:
SELECT emp1.emp_id, COUNT(*) AS Subordinates FROM employee AS emp1 LEFT JOIN employee AS emp2 ON emp1.emp_id = emp2.super_id GROUP BY emp1.emp_id;
COUNT(*)会统计所有返回行,包括LEFT JOIN后无下属员工对应的NULL行,导致无下属的员工被错误统计为1个下属。
- 调整后语句问题:
SELECT emp1.emp_id, IF (COUNT(*)>1, COUNT(*), NULL) AS Subordinates FROM employee AS emp1 LEFT JOIN employee AS emp2 ON emp1.emp_id = emp2.super_id GROUP BY emp1.emp_id;
IF(COUNT(*)>1, COUNT(*), NULL)的逻辑错误,会把仅有1个下属的员工误判为无下属(返回NULL),不符合统计需求。
正确解法
方法一:用COUNT(列名)替代COUNT(*)
SELECT emp1.emp_id, COUNT(emp2.emp_id) AS Subordinates FROM employee AS emp1 LEFT JOIN employee AS emp2 ON emp1.emp_id = emp2.super_id GROUP BY emp1.emp_id;
COUNT(emp2.emp_id)会自动忽略NULL值:当员工无下属时,emp2.emp_id为NULL,计数结果为0;有下属时统计实际下属数量,完全匹配需求。
方法二:使用子查询
SELECT e.emp_id, (SELECT COUNT(*) FROM employee WHERE super_id = e.emp_id) AS Subordinates FROM employee e;
对每个员工直接查询其作为上级的下属数量,逻辑更直观,无下属时返回0,同样能得到正确结果。
验证结果
两种方法都会输出正确统计结果:
| emp_id | Subordinates |
|---|---|
| 100 | 3 |
| 101 | 0 |
| 102 | 3 |
| 103 | 0 |
| 104 | 0 |
| 105 | 0 |
| 106 | 2 |
| 107 | 0 |
| 108 | 0 |
内容的提问来源于stack exchange,提问作者Aspiring Guy
相关产品推荐
相关产品推荐

