如何用SQL查询员工表的管理幅度?含自连接与子查询方案
统计经理的直接下属人数(自连接&子查询实现)
员工表结构及数据
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
|---|---|---|---|---|---|---|---|
| 7698 | BLAKE | MANAGER | 7839 | 05/01/1981 | 2850 | - | 30 |
| 7839 | KING | PRESIDENT | - | 11/17/1981 | 5000 | - | 10 |
| 7782 | CLARK | MANAGER | 7839 | 06/09/1981 | 2450 | - | 10 |
需求:已知EMPNO与MGR列使用相同的4位数字,编写SQL查询返回每位经理的直接下属人数,分别通过自连接和子查询实现。期望输出格式如下:
期望输出格式
| (经理)ENAME | (直接下属)COUNT_OF_ENAME |
|---|---|
| BLAKE | n |
| KING | n |
| CLARK | n |
方法一:自连接实现
通过自连接关联经理和下属,再按经理分组统计数量,用LEFT JOIN确保无下属的经理也能显示(数量为0):
SELECT m.ename AS "(经理)ENAME", COUNT(e.empno) AS "(直接下属)COUNT_OF_ENAME" FROM emp m LEFT JOIN emp e ON m.empno = e.mgr GROUP BY m.empno, m.ename ORDER BY m.ename;
- 用
LEFT JOIN替代内连接,避免遗漏没有下属的经理; - 按
m.empno分组是为了避免重名经理的统计错误,同时保留m.ename用于展示。
方法二:子查询实现
通过子查询单独统计每个经理的下属数,再关联员工表获取经理姓名:
SELECT ename AS "(经理)ENAME", (SELECT COUNT(*) FROM emp e WHERE e.mgr = emp.empno) AS "(直接下属)COUNT_OF_ENAME" FROM emp WHERE job IN ('MANAGER', 'PRESIDENT'); -- 仅筛选经理角色,若普通员工也可能有下属可删除此条件
- 子查询会针对每个员工(作为经理)实时统计其下属数量;
WHERE条件用于过滤出明确的经理角色,按需调整即可。
对你原有查询的调整
你之前的关联查询已经找到了经理和下属的对应关系,只需补充分组统计逻辑即可:
SELECT m.ename AS "(经理)ENAME", COUNT(e.empno) AS "(直接下属)COUNT_OF_ENAME" FROM emp e RIGHT JOIN emp m ON e.mgr = m.empno GROUP BY m.empno, m.ename ORDER BY m.ename;
这里用RIGHT JOIN确保所有经理都被包含,和方法一的LEFT JOIN逻辑一致,只是表的关联顺序调换了。
内容的提问来源于stack exchange,提问作者3PLanalyst
相关产品推荐
相关产品推荐

