4

I want to write an sql query , and want to get the dept name from DEPT table who has no employees assigned in EMP table.

Table Structure:

EMP
EMPNO   ENAME    DEPTNO

DEPT
DEPTNO   DNAME

So I like to know those DEPT who has no employees association.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Adil Bhatty
  • 17,190
  • 34
  • 81
  • 118

10 Answers10

9

It's only correct with NOT EXISTS

SELECT D.DNAME
FROM DEPT D
WHERE
 NOT EXISTS (SELECT * FROM EMP E WHERE D.DEPTNO = E.DEPTNO)

or EXCEPT, more complex in this case

SELECT D.DNAME
FROM DEPT D
EXCEPT
SELECT D.DNAME
FROM DEPT D
JOIN 
EMP E WHERE D.DEPTNO = E.DEPTNO

Both should give the same plan (with a left anti semi join)

Notes on other answers:

  • A LEFT JOIN will give one row per employee. You'd need DISTINCT. Which compromises the plan compared with NOT EXISTS

  • NOT IN will give false results if there is an Employee who has no Department. NOT IN with a NULL in the list fails

So generally one should use NOT EXISTS or EXCEPT

gbn
  • 422,506
  • 82
  • 585
  • 676
  • Could you add info about which dbms you tried? On Oracle, the first query will generate an anti join (hash or nl depending on data distribution) whereas the second query causes results in two sorts. – Ronnis Dec 28 '10 at 12:28
  • @Ronnis: SQL server. Based on experience and this http://stackoverflow.com/questions/4249891/combining-datasets-with-except-versus-checking-on-is-null-in-a-left-join/4249958#4249958 – gbn Dec 28 '10 at 12:31
4
select dname from dept where deptno not in (select deptno from emp)
Oli
  • 2,370
  • 2
  • 26
  • 42
  • 1
    Let's hope every employee has a department. CEO may not have a department and deptno could be NULL = fail... – gbn Dec 28 '10 at 11:51
4
SELECT D.DNAME
FROM DEPT D
LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE E.DEPTNO IS NULL

UPDATE:

@bernd_k pointed out that DISTINCT is not necessary (SELECT DISTINCT D.DNAME ...) in this case - even without it no duplicate departments will be returned.

Marek Grzenkowicz
  • 17,024
  • 9
  • 81
  • 111
  • 1
    @bernd_k: you'd get one row per EMP. So you need DISTINCT. Which was added after on a quick update so does not show as an edit... – gbn Dec 28 '10 at 11:45
  • 1
    @gbn but those where excluded by the where clause. I get no duplicates for the unjoined departments. DISTINCT is not needed – bernd_k Dec 28 '10 at 11:51
  • 1
    @bernd_k: this is actually a special case. Generally, you usually need DISTINCT to compensate for multiple rows caused by the JOIN. – gbn Dec 28 '10 at 11:52
  • @gbn In those cases, when I only select columns from the left table I prefer the where in ... construct, to avoid DISTINCT – bernd_k Dec 28 '10 at 11:56
  • @gbn admitted, but the case to avoid distinct is the where x in (select y ...) case and that is reliable. Possible Nulls in subselect don't matter. – bernd_k Dec 28 '10 at 12:09
1
SELECT D.DEPTNO
FROM EMP E
JOIN DEPT D ON D.DEPTNO = E.DEPTNO (+)
WHERE E.EMPNO IS NULL;
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
nuebe
  • 11
  • 1
1
Select DName 
from DEPT
where DName NOT IN (Select Distinct EMP.DName from EMP);
Marek Grzenkowicz
  • 17,024
  • 9
  • 81
  • 111
Lucky Rana
  • 1,030
  • 1
  • 12
  • 20
1

You can select these departments from dept table whom numbers are not present in emp table:

SELECT dname
FROM dept 
WHERE deptno 
NOT IN (SELECT DISTINCT deptno 
FROM emp);
Karol Borkowski
  • 532
  • 7
  • 19
0
select  x.DEPTNO from dept x where x.DEPTNO not in 
(select d.DEPTNO from department d join
employee e where e.deptid=d.DEPTNO)

The sub query is used to get all the employees who are associated with a department:

select d.DEPTNO from department d join
employee e where e.deptid=d.DEPTNO
 and using select  x.DEPTNO from dept x where x.DEPTNO 

not in will give the employees who do not belong to any department.

Markus
  • 2,071
  • 4
  • 22
  • 44
Sonia Jain
  • 143
  • 2
  • 10
  • Thank you for this code snippet, which might provide some limited short-term help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Feb 21 '18 at 09:33
0

The below is not using any except or not in and performance wise it is better

select d.dname 
from emp e right
join dept d on e.deptno=d.deptno
group by d.dname
having count(e.empno)=0
Marek Grzenkowicz
  • 17,024
  • 9
  • 81
  • 111
Sonia Jain
  • 143
  • 2
  • 10
0
SELECT ID,NAME,SAL,DEPTNAME,DEPTID
FROM emp
FULL JOIN
DEPT
ON EMP.departmentid=DEPT.DEPTID
WHERE DEPTID IS NULL
Dmitry
  • 6,716
  • 14
  • 37
  • 39
0

Find department_id for departments that do not contain the job_id ST_MAN

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 18 '22 at 10:38