Suppose the table is:
employee_id | branch | role |
---|---|---|
1 | A | admin |
2 | A | engineer |
3 | A | finance |
4 | B | admin |
5 | B | finance |
6 | C | engineer |
How can I find the departments that do not have all the roles?
In this example:
- Department A has all the roles.
- Department B does not have engineer role.
- Department C does not have admin and finance roles.
What would be the SQL query to get this result?
Ideally, the output should be
branch | role |
---|---|
B | engineer |
C | admin |
C | finance |
3
Answers
We can use a calendar table left anti join approach here:
Note that
role
was a reserved keyword in MySQL versions earlier than 8+. If you are using an earlier version, you should avoid usingrole
as a column name.We can use
CROSS JOIN
to build all possible combinations of branch and role and thenNOT EXISTS
to exclude those combinations that really exist in the table:Note: The column "role" was renamed to "roles" in my query to prevent that "role" will be read as SQL key word.
You can use aggregation.
If you want just the branches:
If you want all the rows of the table for the branches returned by the above query use also the operator
IN
:See the demo.