I’m working on a little SQL exercise, and am scratching my head an this problem.
I am trying to find all the Employees to whom no other employee reports to.
This is what the employees
table looks like:
EmployeeId LastName FirstName Title ReportsTo 1 Adams Andrew General Manager null 2 Edwards Nancy Sales Manager 1 3 Peacock Jane Sales Support Agent 2 4 Park Margaret Sales Support Agent 2 5 Johnson Steve Sales Support Agent 2 6 Mitchell Michael IT Manager 1 7 King Robert IT Staff 6 8 Callahan Laura IT Staff 6
I thought a straightforward one of these queries would do it:
SELECT * FROM employees Where EmployeeId not in (select ReportsTo from employees) SELECT * FROM employees Where EmployeeId not in (ReportsTo)
But those return the following results, which isn’t what I’m looking for:
EmployeeId LastName FirstName Title ReportsTo 2 Edwards Nancy Sales Manager 1 3 Peacock Jane Sales Support Agent 2 4 Park Margaret Sales Support Agent 2 5 Johnson Steve Sales Support Agent 2 6 Mitchell Michael IT Manager 1 7 King Robert IT Staff 6 8 Callahan Laura IT Staff 6
Why is NOT IN
returning items that are definitely in that column? How would I go about returning items not in ReportsTo
if I am using NOT IN
incorrectly?
Advertisement
Answer
The problem with your 1st query is that you use NOT IN
with a list that contains a NULL
value.
So a comparison of an EmployeeId
like say 5:
5 NOT IN (null, 1, 2, 6)
will return NULL
, because any comparison to NULL
returns NULL
and that EmployeeId
will not be included in the results.
Change to:
SELECT * FROM employees Where EmployeeId not in ( select ReportsTo from employees where ReportsTo is not null );
See the demo.
Results:
| EmployeeId | LastName | FirstName | Title | ReportsTo | | ---------- | -------- | --------- | ------------------- | --------- | | 3 | Peacock | Jane | Sales Support Agent | 2 | | 4 | Park | Margaret | Sales Support Agent | 2 | | 5 | Johnson | Steve | Sales Support Agent | 2 | | 7 | King | Robert | IT Staff | 6 | | 8 | Callahan | Laura | IT Staff | 6 |