Reputation: 45
Employees with no subordinates should be listed as having zero subordinates should also be displayed by this query. I can currently return all employees with subordinates, but I can't seem to display employees with zero subordinates.
Here is the code so far:
SELECT s.empno, s.ename, COUNT(*) as "Num_subordinates"
FROM emp e
JOIN emp s ON s.empno=e.super
GROUP BY s.empno, s.ename;
Upvotes: 2
Views: 5391
Reputation: 4965
A few solutions for you problem:
1) grouped auto-join:
SELECT s.empno, s.ename, COUNT(*) as "Num_subordinates"
FROM emp e RIGHT JOIN emp s ON s.empno=e.super
GROUP BY s.empno, s.ename;
2) left join with aggregate subordinate counts:
SELECT s.*, c.num_subordinates as "Num_subordinates"
FROM emp s LEFT JOIN (SELECT super AS empno, COUNT(*) FROM emp GROUP BY super) AS c
ON c.empno = s.empno;
or using CTE:
WITH c AS (SELECT super AS empno, COUNT(*) FROM emp GROUP BY super)
SELECT s.*, c.num_subordinates as "Num_subordinates"
FROM emp s LEFT JOIN c
ON c.empno = s.empno;
3) using scalar sub-query:
SELECT s.*, (SELECT COUNT(*) FROM emp WHERE super=s.empno) AS "Num_subordinates"
FROM emp s;
Upvotes: 0
Reputation: 92845
UPDATED
Assuming that data is similar to the following
| EMPNO | ENAME | SUPER |
------------------------------
| 1 | Manager1 | (null) |
| 2 | Employee1 | 1 |
| 3 | Employee2 | 1 |
| 4 | Employee3 | 1 |
| 5 | Manager2 | (null) |
| 6 | Employee5 | 5 |
| 7 | Employee6 | (null) |
A version with a subquery
SELECT e.empno,
e.ename,
(SELECT COUNT(*)
FROM emp
WHERE super = e.empno) "Num_subordinates"
FROM emp e;
A version with a JOIN
. You have to use LEFT JOIN
since INNER JOIN
filters out necessary rows and as JW correctly pointed out you need to COUNT
on s.empno
rather then *
.
SELECT e.empno,
e.ename,
COUNT(s.empno) "Num_subordinates"
FROM emp e LEFT JOIN emp s
ON s.super = e.empno
GROUP BY e.empno, e.ename
ORDER BY e.empno
Output for both queries
| EMPNO | ENAME | NUM_SUBORDINATES |
----------------------------------------
| 1 | Manager1 | 3 |
| 2 | Employee1 | 0 |
| 3 | Employee2 | 0 |
| 4 | Employee3 | 0 |
| 5 | Manager2 | 1 |
| 6 | Employee5 | 0 |
| 7 | Employee6 | 0 |
SQLFiddle (for both queries)
Upvotes: 1
Reputation: 263933
The only missing in your statement is to use LEFT JOIN
rather than INNER JOIN
. You also need to specify the ID
instead of *
when counting in LEFT JOIN
so you will not yield 1
on the COUNT()
if the employee don't have subordinate.
SELECT e.empno, e.ename, COUNT(s.empno) as "Num_subordinates"
FROM emp e
LEFT JOIN emp s ON s.empno = e.super
GROUP BY e.empno, e.ename
To further gain more knowledge about joins, kindly visit the link below:
Upvotes: 4