我有这样的架构:
// 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
我想要做的是选择特定用户尚未获得的所有badge_types
。在上面的示例中,调用查询:
user_id = 5
返回badge_type_id
2
和3
user_id = 6
返回empty
设置(用户已获得所有这些)
user_id = 19
返回badge_type_id
1
和3
我可以使用INTERSECT
子句执行此操作。但我想知道是否可以用简单的JOIN
来完成它?任何帮助将不胜感激。
答案 0 :(得分:13)
SELECT bt.name
FROM BADGE_TYPES bt
LEFT JOIN BAGDES b ON b.badge_type_id = bt.id
AND b.user_id = ?
WHERE b.id IS NULL
SELECT bt.name
FROM BADGE_TYPES bt
WHERE NOT EXISTS(SELECT NULL
FROM BADGES b
WHERE b.badge_type_id = bt.id
AND b.user_id = ?)
SELECT bt.name
FROM BADGE_TYPES bt
WHERE bt.id NOT IN (SELECT b.badge_type_id
FROM BADGES b
WHERE b.user_id = ?)
如果列是not nullable, LEFT JOIN/IS NULL is the best choice。如果他们are nullable, NOT EXISTS
and NOT IN
are the best choice。