use*_*976 1 sql postgresql join
我怎么能做一些像加入的相反的事情?例如,从这两个表中选择表alice中不在表bob中的值:
alice:
id|name
--+----
1 |one
2 |two
3 |three
6 |six
7 |seven
bob:
id|a_id
--+----
15|1
16|2
17|3
Run Code Online (Sandbox Code Playgroud)
得到这个:
result:
name
----
six
seven
Run Code Online (Sandbox Code Playgroud)
这称为反连接.
一般的想法是执行左,右或全外连接,并过滤以仅查找外侧为空的行.
对于你的例子,这是一个左反半连接:
select a.id, a.name
from alice a
left outer join bob b on (a.id = b.a_id)
where b.id is null;
Run Code Online (Sandbox Code Playgroud)
但是也可以通过完整的外部连接找到两侧的不匹配:
select a.id, a.name
from alice a
full outer join bob b on (a.id = b.a_id)
where b.id is null
or a.id is null;
Run Code Online (Sandbox Code Playgroud)
对于左反连接方法,您可以改为使用not exists:
select a.id, a.name
from alice a
where not exists (select 1 from bob b where b.a_id = a.id);
Run Code Online (Sandbox Code Playgroud)
虽然在实践中PostgreSQL仍会将其转换为连接形式.
可以使用not in:
select a.id, a.name
from alice a
where a.id not in (select b.a_id from bob);
Run Code Online (Sandbox Code Playgroud)
但:
你必须确保有可以在子查询结果没有空,因为1 not in (2, null)是null没有true;
效率低得多
所以通常使用反连接或存在子查询是非常优选的.
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |