能否通过JOIN实现需求?查询未与ID=10用户建立关联的用户
解决未关联用户的SQL查询问题
嘿,我来帮你搞定这个SQL查询的问题!你之前用左连接的写法没得到预期结果,问题出在WHERE条件的处理上——咱们先理清楚问题所在,再给你几个靠谱的解决方案。
为什么你的原SQL不对?
你写的语句:
select distinct * from USER left join LINK on USER.id = LINK.id1 where LINK.id1 != 10
这里有两个关键问题:
- 左连接后,那些没有和任何Link记录关联的用户,
LINK.id1会是NULL,而NULL != 10的结果是未知,会被WHERE条件直接过滤掉,导致真正需要的未关联用户没被选中。 DISTINCT其实是多余的,因为User.id是主键,每条用户记录都是唯一的,不会出现重复。
正确的解决方案
方案1:用NOT EXISTS(推荐,高效直观)
这是最贴合你需求的写法,直接检查当前用户是否不存在和ID=10的关联记录:
SELECT u.id, u.pseudo FROM User u WHERE NOT EXISTS ( SELECT 1 FROM Link l WHERE l.id1 = 10 AND l.id2 = u.id );
解释:子查询会检查是否存在一条Link记录,其中id1=10且id2是当前用户的ID。如果不存在这条记录,就会把该用户选出来,完全匹配你的需求。
如果你的Link表是双向存储关联的(比如用户A和B关联,会同时存(10, x)和(x, 10),或者只存其中一种但你需要排除两种情况),可以调整子查询:
SELECT u.id, u.pseudo FROM User u WHERE NOT EXISTS ( SELECT 1 FROM Link l WHERE (l.id1 = 10 AND l.id2 = u.id) OR (l.id1 = u.id AND l.id2 = 10) );
方案2:用左连接+IS NULL(修正你原来的思路)
如果你坚持想用左连接,需要把关联条件放在ON里,而不是WHERE里,这样才能保留左连接产生的NULL记录:
SELECT u.id, u.pseudo FROM User u LEFT JOIN Link l ON l.id1 = 10 AND l.id2 = u.id WHERE l.id1 IS NULL;
解释:左连接会尝试为每个用户匹配id1=10且id2是当前用户的Link记录,匹配不到的话l.id1就是NULL,WHERE条件筛选出这些NULL的情况,就是未关联的用户。
额外提醒:排除用户10自己
如果你的需求里不需要包含ID=10的用户自己,可以在WHERE条件里加上u.id != 10:
SELECT u.id, u.pseudo FROM User u WHERE u.id != 10 AND NOT EXISTS ( SELECT 1 FROM Link l WHERE l.id1 = 10 AND l.id2 = u.id );
内容的提问来源于stack exchange,提问作者Vinz
相关产品推荐
相关产品推荐

