I have a schema like this:
// table badge_types
id | name
+++|++++++++++
1 | mentor
2 | proctor
3 | doctor
// table badges
id | badge_type_id | user_id
+++|+++++++++++++++|++++++++
1 | 1 | 5
2 | 1 | 6
3 | 2 | 6
4 | 3 | 6
5 | 2 | 19
6 | 3 | 20
What I want to do, is select all badge_types that a particular user has not yet gotten. In the above example, calling the query for:
user_id = 5 returns badge_type_id 2 and 3
user_id = 6 returns empty set (user got all of them already)
user_id = 19 returns badge_type_id 1 and 3
I can do this with an INTERSECT clause. But I’m wondering if it can be done with a simple JOIN? Any help would be appreciated.
Using LEFT JOIN/IS NULL:
Using NOT EXISTS
Using NOT IN
MySQL
If the columns are not nullable, LEFT JOIN/IS NULL is the best choice. If they are nullable,
NOT EXISTSandNOT INare the best choice.SQL Server
Mind that on SQL Server,
NOT INandNOT EXISTSperform better than LEFT JOIN /IS NULL if the columns in question are not nullable.Oracle
For Oracle, all three are equivalent but LEFT JOIN/IS NULL and NOT EXISTS are preferable if columns aren’t nullable.