如何查找未加入的记录?
我有两张连在一起的桌子。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
或者就像这个帖子上的其他人所说的:
Or like some other people on this thread says:
下图将有助于理解 SQL LET JOIN :
The following image will help to understand SQL LET JOIN :
另一种方法:
如果需要将其他“where”子句附加到内部查询,则“exists”方法很有用。
Another approach:
The "exists" approach is useful if there is some other "where" clause you need to attach to the inner query.
如果使用外连接,您可能会获得更好的性能(比使用“not in”):
You will probably get a lot better performance (than using 'not in') if you use an outer join:
如果是一个连接,速度相当快,但是当我们从拥有大约 5000 万条记录和 4 个或更多由于外键连接的数据库中删除记录时,需要几分钟才能完成。
使用 WHERE NOT IN 条件要快得多,如下所示:
如果我们没有配置级联删除,我也可以推荐这种删除方法。
这个查询只需要几秒钟。
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:
I can also recommended this approach for deleting in case we don't have configured cascade delete.
This query takes only a few seconds.
第一种方法是
第二种方法
第一种方法非常昂贵。 第二种方法更好。
使用 PostgreSql 9.4,我执行了“解释查询”功能,并将第一个查询的成本设为 cost=0.00..1982043603.32。
相反,连接查询的成本为 cost=45946.77..45946.78
例如,我搜索与任何车辆不兼容的所有产品。 我有 100k 个产品和超过 100 万个兼容性。
连接查询花费了大约 5 秒,而子查询版本在 3 分钟后从未结束。
The first approach is
the second approach is
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.
The join query spent about 5 seconds, instead the subquery version has never ended after 3 minutes.
另一种写法 哎呀
,被内森打败了:)
Another way of writing it
Ouch, beaten by Nathan :)
这将保护您免受 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)