如何查找未加入的记录?

时间:2008-09-29 22:56:45

标签: sql select join anti-join

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

A有很多B

通常你会这样做:

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

从b中记录的所有记录。

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

11 个答案:

答案 0 :(得分:70)

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

答案 1 :(得分:16)

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

答案 2 :(得分:5)

另一种方法:

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

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

答案 3 :(得分:4)

SELECT id FROM a
EXCEPT
SELECT a_id FROM b;

答案 4 :(得分:2)

从id不在的地方选择*(从b中选择a_id)

答案 5 :(得分:1)

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

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

答案 6 :(得分:1)

以下图片将有助于理解SQL LET JOIN

enter image description here

答案 7 :(得分:0)

另一种写作方式

select a.*
from a 
left outer join b
on a.id = b.id
where b.id is null
哎哟,被内森殴打:)

答案 8 :(得分:0)

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

从id不在的地方选择*(从b中选择[a id] [a id]不为空

答案 9 :(得分:0)

在一次加入的情况下它很快,但是当我们从数据库中删除记录时,由于外键有大约50亿个记录和4个以上的连接,这需要几分钟的时间来完成。 使用速度要快得多,而不是这样:

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 :(得分: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的产品和超过100万的兼容性。

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

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