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

相关推荐
hz567897 分钟前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC12 分钟前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
程序员Sunday14 分钟前
MySQL 为什么使用 B+ 树索引?把范围查询、回表和覆盖索引连起来
数据库·mysql
半杯咖啡半行码35 分钟前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
小米里的大麦1 小时前
16 MySQL 事务
数据库·mysql
西柚小萌新1 小时前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库
邓工说电2 小时前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技
adinnet20262 小时前
企业微调大模型(Fine-tuning):先吃透 RAG 还是先训自己的模型
大数据·数据库
上位机妹子3 小时前
EF Core 两种继承映射:每层次一张表(TPH)与每类型一张表(TPT)
数据库·c#·.netcore·ef core
小马同学-3 小时前
Redis消息队列与客户端编程
数据库·redis