如何查找未加入的记录?

发布于 2024-07-07 11:40:25 字数 180 浏览 11 评论 0原文

我有两张连在一起的桌子。

A 有许多 B

通常您会这样做:

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

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

如何只获取a中的记录而b中没有任何记录?

I have two tables that are joined together.

A has many B

Normally you would do:

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

To get all of the records from a that has a record in b.

How do I get just the records in a that does not have anything in b?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

忆伤 2024-07-14 11:40:25
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
select * from a where id not in (select a_id from b)

Or like some other people on this thread says:

select a.* from a
left outer join b on a.id = b.a_id
where b.a_id is null
爱情眠于流年 2024-07-14 11:40:25
select * from a
left outer join b on a.id = b.a_id
where b.a_id is null
select * from a
left outer join b on a.id = b.a_id
where b.a_id is null
优雅的叶子 2024-07-14 11:40:25

下图将有助于理解 SQL LET JOIN

在此处输入图像描述

The following image will help to understand SQL LET JOIN :

enter image description here

爱你不解释 2024-07-14 11:40:25

另一种方法:

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

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

Another approach:

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

The "exists" approach is useful if there is some other "where" clause you need to attach to the inner query.

撕心裂肺的伤痛 2024-07-14 11:40:25
SELECT id FROM a
EXCEPT
SELECT a_id FROM b;
SELECT id FROM a
EXCEPT
SELECT a_id FROM b;
罪歌 2024-07-14 11:40:25

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

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

You will probably get a lot better performance (than using 'not in') if you use an outer join:

select * from a left outer join b on a.id = b.a_id where b.a_id is null;
自由如风 2024-07-14 11:40:25
SELECT <columnns>
FROM a WHERE id NOT IN (SELECT a_id FROM b)
SELECT <columnns>
FROM a WHERE id NOT IN (SELECT a_id FROM b)
清欢 2024-07-14 11:40:25

如果是一个连接,速度相当快,但是当我们从拥有大约 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)

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

In case of one join it is pretty fast, but when we are removing records from database which has about 50 milions records and 4 and more joins due to foreign keys, it takes a few minutes to do it.
Much faster to use WHERE NOT IN condition like this:

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)

I can also recommended this approach for deleting in case we don't have configured cascade delete.
This query takes only a few seconds.

烟花易冷人易散 2024-07-14 11:40:25

第一种方法是

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 个产品和超过 100 万个兼容性。

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

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

The first approach is

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

the second approach is

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

The first approach is very expensive. The second approach is better.

With PostgreSql 9.4, I did the "explain query" function and the first query as a cost of cost=0.00..1982043603.32.
Instead the join query as a cost of cost=45946.77..45946.78

For example, I search for all products that are not compatible with no vehicles. I've 100k products and more than 1m compatibilities.

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

The join query spent about 5 seconds, instead the subquery version has never ended after 3 minutes.

绝對不後悔。 2024-07-14 11:40:25

另一种写法 哎呀

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

,被内森打败了:)

Another way of writing it

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

Ouch, beaten by Nathan :)

快乐很简单 2024-07-14 11:40:25

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

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

This will protect you from nulls in the IN clause, which can cause unexpected behavior.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文