SQL中EXISTS、NOT EXISTS用法及两条EXISTS查询返回全表原因解析
两段SQL返回全表的具体原因
两个语句返回全表的核心逻辑都是exists的判断规则,具体差异如下:
- 第一段SQL的过滤条件是
exists (select null):exists只判断子查询是否返回至少1行,完全不关心返回的内容是什么。这里的子查询是固定的select null,不需要依赖外层表的任何字段值,不管外层遍历customer表的哪一行,这个子查询永远会返回结果,因此条件恒为真,必然返回customer全表数据。 - 第二段SQL的子查询属于无关联子查询,子查询内部没有任何和外层customer表的关联绑定条件,只要整张customer表中存在至少1条满足
residence = 'los angeles'、age>20且age<40的记录,那么不管外层遍历哪一行,子查询都会返回结果,exists条件恒为真,因此也返回全表。如果customer表中没有符合子查询条件的记录,第二段SQL会返回空结果,这是它和第一段SQL的核心区别——第一段SQL无论表中有什么数据,永远返回全表。
EXISTS和NOT EXISTS的作用 EXISTS是SQL中的布尔运算符,用于校验子查询是否有结果返回:
- 只要子查询返回至少1条记录,
EXISTS运算结果就为真,对应的外层行就会被保留到最终结果集中 EXISTS不校验子查询返回的具体内容,因此select 1、select null、select 字段在EXISTS子查询中效果完全一致- 实际使用中通常搭配关联子查询实现跨表匹配逻辑,比如查询所有有有效订单的用户,写法示例:
select * from user u where exists ( select 1 from order o where o.user_id = u.id -- 关联条件将子查询和外层表绑定 )
NOT EXISTS是EXISTS的逻辑反义:
- 只有当子查询没有返回任何记录时,
NOT EXISTS运算结果才为真,对应的外层行才会被保留 - 通常用于实现“不存在匹配项”的查询需求,比如查询所有没有下过订单的用户,只需要将上面示例中的
EXISTS替换为NOT EXISTS即可。
内容的提问来源于stack exchange,提问作者Shrinithi S
相关产品推荐
相关产品推荐

