我有这个users
表:
和这个relationships
表:
因此,每个用户都与relationships
表中的另一个用户配对。
现在,我想在两列(users
或relationships
)中的任意一列中获取user_id
表中不在pair_id
表中的列表。
我该怎么写这个查询?
首先尝试:
SELECT users.id
FROM users
LEFT OUTER JOIN relationships
ON users.id = relationships.user_id
WHERE relationships.user_id IS NULL;
输出:
这应该只显示2个结果:5和6.结果8不正确,因为它已经存在于relationships
中。当然我知道查询不正确,我该如何解决呢?
答案 0 :(得分:4)
您需要与on
语句中的两个值进行比较:
SELECT u.id
FROM users u LEFT OUTER JOIN
relationships r
ON u.id = r.user_id or u.id = r.pair_id
WHERE r.user_id IS NULL;
通常,or
子句中的on
可能效率低下。我建议用两个not exists
语句替换它:
SELECT u.id
FROM users u
WHERE NOT EXISTS (SELECT 1 FROM relationships r WHERE u.id = r.user_id) AND
NOT EXISTS (SELECT 1 FROM relationships r WHERE u.id = r.pair_id);
答案 1 :(得分:2)
我喜欢集合运算符
select id from users
except
select user_id from relationships
except
select pair_id from relationships
或
select id from users
except
(select user_id from relationships
union
select pair_id from relationships
)
答案 2 :(得分:2)
这是一个特殊情况:
Select rows which are not present in other table
我认为这将是最简单和最快的:
SELECT u.id
FROM users u
WHERE NOT EXISTS (
SELECT 1
FROM relationships r
WHERE u.id IN (r.user_id, r.pair_id)
);
在Postgres中,u.id IN (r.user_id, r.pair_id)
只是简称:(u.id = r.user_id OR u.id = r.pair_id)
表达式在内部以这种方式转换,可以从EXPLAIN ANALYZE
观察到。
要清除评论中的推测:现代版本的Postgres将使用user_id
和/或pair_id
上的匹配索引进行此类查询。
答案 3 :(得分:0)
类似的东西:
select u.id
from users u
where u.id not in (select r.user_id from relationships r)
and u.id not in (select r.pair_id from relationships r)