76

我有两个连接在一起的表。

A有很多B

通常你会这样做:

select * from a,b where b.a_id = a.id

从a中获取所有在b中有记录的记录。

如何仅获取 a 中没有 b 中任何内容的记录?

4

11 回答 11

118
select * from a where id not in (select a_id from b)

或者就像这个线程上的其他人说的:

select a.* from a
left outer join b on a.id = b.a_id
where b.a_id is null
于 2008-09-29T22:57:50.423 回答
26
select * from a
left outer join b on a.id = b.a_id
where b.a_id is null
于 2008-09-29T23:00:23.617 回答
6

另一种方法:

select * from a where not exists (select * from b where b.a_id = a.id)

如果您需要将其他一些“where”子句附加到内部查询,则“exists”方法很有用。

于 2008-09-29T23:01:10.150 回答
4
SELECT id FROM a
EXCEPT
SELECT a_id FROM b;
于 2012-03-13T10:42:44.707 回答
2

如果您使用外连接,您可能会获得更好的性能(比使用'not in'):

select * from a left outer join b on a.id = b.a_id where b.a_id is null;
于 2008-09-29T23:05:52.527 回答
2

下图将有助于理解 SQL LET JOIN

在此处输入图像描述

于 2020-05-12T10:28:30.250 回答
1
SELECT <columnns>
FROM a WHERE id NOT IN (SELECT a_id FROM b)
于 2008-09-29T22:57:55.633 回答
0

另一种写法

select a.*
from a 
left outer join b
on a.id = b.id
where b.id is null

哎哟,被内森打败了:)

于 2008-09-29T23:06:44.537 回答
0

这将保护您免受 IN 子句中的空值的影响,这可能导致意外行为。

select * from a where id not in (select [a id] from b where [a id] is not null )

于 2008-09-29T23:14:45.670 回答
0

在一次连接的情况下,它非常快,但是当我们从具有大约 5000 万条记录和 4 个或更多连接的数据库中删除记录时,由于外键,它需要几分钟才能完成。像这样使用 WHERE NOT IN 条件要快得多:

select a.* from a
where a.id NOT IN(SELECT DISTINCT a_id FROM b where a_id IS NOT NULL)
//And for more joins
AND a.id NOT IN(SELECT DISTINCT a_id FROM c where a_id IS NOT NULL)

如果我们没有配置级联删除,我也可以推荐这种删除方法。这个查询只需要几秒钟。

于 2018-01-05T15:38:01.270 回答
0

第一种方法是

select a.* from a where a.id  not in (select b.ida from b)

第二种方法是

select a.*
  from a left outer join b on a.id = b.ida
  where b.ida is null

第一种方法非常昂贵。第二种方法更好。

使用 PostgreSql 9.4,我执行了“解释查询”功能,并将第一个查询作为cost=0.00..1982043603.32的成本。而是将连接查询作为cost=45946.77..45946.78的成本

例如,我搜索所有与无车辆不兼容的产品。我有 100k 产品和超过 1m 的兼容性。

select count(*) from product a left outer join compatible c on a.id=c.idprod where c.idprod is null

连接查询花费了大约 5 秒,而子查询版本在 3 分钟后从未结束。

于 2018-01-16T10:09:55.353 回答