《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 中最常见的字符串函数。

相关推荐
进阶的小木桩4 分钟前
mysql 安装问题解决方案记录
数据库·mysql
2601_962071571 小时前
如何利用SpringSecurity进行认证与授权
java·服务器·数据库
山峰哥1 小时前
数据库工程与查询优化案例深度复盘‌
数据库·sql·oracle·编辑器·深度优先·宽度优先
IT大白鼠1 小时前
MSF数据库与资产管理——专业渗透测试流程
数据库·安全·msf
IvorySQL1 小时前
PostgreSQL 日报|内核多项缺陷修复与数据校验补丁推进(8 月 27 日)
数据库·postgresql·区块链
风吹心凉1 小时前
Agent大脑-RAG知识库
数据库
VALENIAN瓦伦尼安教学设备1 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法
黄俊懿2 小时前
【架构师从入门到进阶】第五章:DNS&CDN&网关优化思路——第十节:网关安全-单向加密
网络·数据库·计算机网络·安全·架构·系统架构·架构师
garmin Chen2 小时前
redis面试题
java·数据库·redis·缓存
小小龙学IT2 小时前
Qt 元对象系统(Meta-Object System)深度解析:从 MOC 到反射式编程
数据库·qt