如何查找未加入的记录?

Posted

技术标签:

【中文标题】如何查找未加入的记录?【英文标题】:How do I find records that are not joined? 【发布时间】:2010-09-14 03:30:13 【问题描述】:

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

A 有很多 B

通常你会这样做:

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

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

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

【问题讨论】:

【参考方案1】:
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

【讨论】:

【参考方案2】:
select * from a
left outer join b on a.id = b.a_id
where b.a_id is null

【讨论】:

我认为这个左外连接将比'in'子句执行得更好,除非查询优化器将它们视为相同...... 确实如此。看看吧。 是的,有趣的是,查询计划有一个额外的链(过滤器)用于左连接,'where in' 被解析为'右反半连接'......不管那是什么...... . 根据that question 中的答案,这不起作用:“如果您在 WHERE 子句中过滤左外连接表,那么您实际上是在创建内连接”【参考方案3】:

另一种方法:

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

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

【讨论】:

【参考方案4】:
SELECT id FROM a
EXCEPT
SELECT a_id FROM b;

【讨论】:

EXCEPT 关键字在 Oracle 中是 MINUS【参考方案5】:

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

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

【讨论】:

【参考方案6】:

下图有助于理解 SQL LET JOIN

【讨论】:

【参考方案7】:
SELECT <columnns>
FROM a WHERE id NOT IN (SELECT a_id FROM b)

【讨论】:

这将非常昂贵,因为引擎必须在开始从 a 中消除元组之前生成完整的子查询。一般来说,这不是一个好主意。【参考方案8】:

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

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

【讨论】:

你最好使用左外连接而不是首先使用 IN 谓词。【参考方案9】:

在一次连接的情况下,它非常快,但是当我们从具有大约 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)

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

【讨论】:

【参考方案10】:

第一种方法是

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

的成本

例如,我搜索所有与 no 车辆不兼容的产品。我有 10 万种产品和超过 100 万种兼容性。

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

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

【讨论】:

【参考方案11】:

另一种写法

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

哎呀,被内森打败了:)

【讨论】:

以上是关于如何查找未加入的记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何加入 Spark 数据集 A 和 B 并标记 A 中未加入的记录?

如何查找未记录版本的 handleGesture 选择器(用于 UIWebView)需要啥样的参数?

如何编写一个 JPQL 查询来查找此连接中未找到的记录?

高效查找最近 k 天内未更新的记录

Access 使用未绑定的组合框查找和添加记录

假设一个表中有多个列有 1000 条记录,如何在整个表中查找重复记录? [复制]