获取两数据集差异用户:LEFT JOIN与MINUS结果差异解析
获取仅存在于单张表的用户信息:LEFT JOIN与MINUS的差异解析
实现预期输出的查询语句
方式一:用FULL OUTER JOIN(或LEFT/RIGHT JOIN组合)
要拿到只在Table_1或只在Table_2里的用户,本质是求两张表的对称差。用FULL OUTER JOIN可以一次性筛选出单边无匹配的记录:
SELECT COALESCE(t1.user1, t2.user1) AS user1, COALESCE(t1.user2, t2.user2) AS user2 FROM Table_1 t1 FULL OUTER JOIN Table_2 t2 ON t1.user1 = t2.user1 AND t1.user2 = t2.user2 WHERE t1.user1 IS NULL OR t2.user1 IS NULL;
如果你的数据库不支持FULL OUTER JOIN,可以拆分两步用UNION合并:
-- 取Table_1有但Table_2没有的用户 SELECT t1.user1, t1.user2 FROM Table_1 t1 LEFT JOIN Table_2 t2 ON t1.user1 = t2.user1 AND t1.user2 = t2.user2 WHERE t2.user1 IS NULL UNION -- 取Table_2有但Table_1没有的用户 SELECT t2.user1, t2.user2 FROM Table_2 t2 LEFT JOIN Table_1 t1 ON t2.user1 = t1.user1 AND t2.user2 = t1.user2 WHERE t1.user1 IS NULL;
方式二:用MINUS(或EXCEPT)结合UNION
利用MINUS(部分数据库用EXCEPT)单方向取差集,再合并两个方向的结果:
-- Table_1独有的用户 SELECT user1, user2 FROM Table_1 MINUS SELECT user1, user2 FROM Table_2 UNION -- Table_2独有的用户 SELECT user1, user2 FROM Table_2 MINUS SELECT user1, user2 FROM Table_1;
LEFT JOIN和MINUS结果不同的核心原因
1. 重复记录的处理逻辑不一样
LEFT JOIN会原封不动保留左表的重复记录:如果左表有两条一模一样的user1+user2组合,只要右表没匹配,这两条都会出现在结果里。MINUS会自动去重:哪怕左表有N条重复组合,MINUS只会返回一次该组合,不会保留重复项。
2. NULL值的匹配规则有差异
LEFT JOIN里,NULL = NULL的比较结果是不成立,不会被判定为匹配。比如某条记录的user1是NULL,就算另一张表也有user1=NULL的同组合记录,LEFT JOIN会认为它们不匹配,两边的记录都会被纳入结果。MINUS在比较时,会把NULL视为相等。如果两张表都有user1=NULL, user2=NULL的记录,MINUS会把这条记录排除,不会出现在差集里。
3. 结果覆盖范围不同
- 单纯的
LEFT JOIN只能查左表减右表的差集,拿不到右表独有的数据,必须结合RIGHT JOIN或UNION才能实现对称差。 MINUS本身是单方向的,但两次MINUS加UNION能实现对称差,但要注意它的去重特性会影响重复记录的输出。
针对你给出的测试数据,上面两种方法都能准确返回预期的5条用户记录。
内容的提问来源于stack exchange,提问作者Math
相关产品推荐
相关产品推荐

