《LeetCode SQL 从入门到进阶(MySQL)》06(下)

EXISTS 与 NOT EXISTS,一篇彻底搞懂存在性查询

大家好,欢迎来到《LeetCode SQL 从入门到进阶(MySQL)》专栏。

上一篇我们学习了子查询(Subquery)的基本使用方法,本篇继续学习另一类在 LeetCode 和实际开发中都非常重要的知识------EXISTS 与 NOT EXISTS。

很多初学者知道 IN,却不知道什么时候应该使用 EXISTS。事实上,它们虽然都可以完成类似的查询,但执行思路完全不同。


一、什么是 EXISTS?

EXISTS 的作用非常简单:

判断子查询是否能够返回至少一条记录。

语法:

复制代码
SELECT ...
FROM 表A
WHERE EXISTS (
    SELECT 1
    FROM 表B
    WHERE ...
);

如果子查询能够返回数据,则 EXISTS 返回 TRUE;否则返回 FALSE。


二、一个简单例子

员工表:

id name
1 Alice
2 Bob
3 Tom

订单表:

id employeeId
1 1
2 1
3 3

现在要求:

查询至少拥有一个订单的员工。

可以写:

复制代码
SELECT *
FROM Employee e
WHERE EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.employeeId = e.id
);

执行过程:

对于 Alice:

复制代码
Orders 中是否存在 employeeId=1?
有。

因此保留。

对于 Bob:

复制代码
Orders 中是否存在 employeeId=2?
没有。

因此过滤。

对于 Tom:

复制代码
Orders 中是否存在 employeeId=3?
有。

因此保留。

最终得到:

name
Alice
Tom

三、为什么写 SELECT 1?

很多人第一次都会疑惑:

复制代码
SELECT 1

为什么不是:

复制代码
SELECT *

实际上:

对于 EXISTS 来说,

数据库并不关心返回什么内容。

它只关心:

有没有记录。

因此:

复制代码
SELECT 1

SELECT *

SELECT id

效果完全一样。

一般推荐:

复制代码
SELECT 1

表达:

我只是判断是否存在。


四、NOT EXISTS

NOT EXISTS 就是:

不存在。

例如:

查询没有任何订单的员工。

复制代码
SELECT *
FROM Employee e
WHERE NOT EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.employeeId = e.id
);

最终得到:

name
Bob

五、EXISTS 与 IN 的区别

例如:

复制代码
SELECT *
FROM Employee
WHERE id IN (
    SELECT employeeId
    FROM Orders
);

和:

复制代码
SELECT *
FROM Employee e
WHERE EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.employeeId=e.id
);

都能得到相同结果。

区别在于:

IN

更像:

先把子查询所有结果取出来,再判断是否属于这个集合。

EXISTS

更像:

找到第一条符合条件的数据后立即停止。

因此:

当子查询数据很多时,

EXISTS 往往更高效。


六、相关子查询

注意:

复制代码
WHERE o.employeeId=e.id

这里:

子查询引用了外层查询的:

复制代码
e.id

这种写法叫:

相关子查询(Correlated Subquery)。

它是 EXISTS 最常见的使用方式。


七、LeetCode 常见应用

常见题型:

  • 查询存在订单的用户

  • 查询没有登录过的用户

  • 查询购买过商品的顾客

  • 查询未参加考试的学生

基本都可以想到:

复制代码
EXISTS

或者:

复制代码
NOT EXISTS

八、常见错误

错误一

忘记关联条件。

错误:

复制代码
WHERE EXISTS (
    SELECT 1
    FROM Orders
)

因为:

只要 Orders 非空,

所有员工都会返回。

正确:

复制代码
WHERE EXISTS (
    SELECT 1
    FROM Orders o
    WHERE o.employeeId=e.id
)

错误二

把 EXISTS 和 IN 混用。

例如:

复制代码
WHERE EXISTS (
    SELECT employeeId
)

EXISTS 不关心返回哪一列。

真正重要的是:

子查询能否返回记录。


九、本章总结

今天学习了:

  • EXISTS:存在至少一条记录。

  • NOT EXISTS:不存在任何记录。

  • EXISTS 常与相关子查询一起使用。

  • EXISTS 判断存在性,IN 判断是否属于集合。

掌握 EXISTS 后,你已经具备解决绝大多数存在性查询问题的能力。

下一篇,我们将进入字符串处理部分,学习 MySQL 中最常见的字符串函数。

相关推荐
考虑考虑10 分钟前
瀚高数据库
数据库·后端·postgresql
dishugj41 分钟前
oracle日志切换三条命令区别
数据库
Patrick在香港1 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
悟道书生1 小时前
(一)Navicate为什么转存结构和数据只转存表而不包含建库?
数据库·oracle
赤龙ERP2 小时前
ERP周报:连接器开闸、国产GPU进场与智能工厂253家
数据库·人工智能·大模型·rpa·erp·企业数字化·builderpattern
lusklusklusk2 小时前
SQL Server补丁版本号为什么“日期新反而版本低”?——GDR、CU、CU+GDR 版本号规则与升级路径详解
数据库
key_3_feng2 小时前
评估与对齐:Agent 自我进化的护栏
前端·数据库·agent
TangGeeA2 小时前
数据库、SQL 与 DB AI
数据库·人工智能·sql
IvorySQL2 小时前
开源数据库进校园| 11 月 3 日,IvorySQL 校园行走进浙大宁波校区:从 PostgreSQL 扩展生态到 AI 实战
数据库·postgresql·开源
福建佰胜张工2 小时前
深度解析 Allen-Bradley 150-B135NBDA 智能电机控制器:选型、参数与工业应用
运维·数据库·单片机·嵌入式硬件·安全·自动化