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

相关推荐
Hrain-AI5 小时前
多 Agent 并行不打架:worktree 隔离与反馈回流落地(附脚本)
网络·数据库·人工智能·架构
净水深流5 小时前
中央厨房冷链技术实践:多温区改造、WMS落地与IoT温控架构
大数据·数据库·人工智能·冷库冷链
l1t5 小时前
测试DuckDB 2.1的match_recognize模式匹配语句
数据库·duckdb
IpdataCloud7 小时前
AI智能体调用工具怎么核验来源IP?归属地、网络类型与代理风险识别(含Python代码)
数据库·python·tcp/ip
曹牧7 小时前
Java:SQL 注入漏洞
数据库
程序员JerrySUN7 小时前
Jetson Edge AI 实战01:Nano、Xavier、Orin 怎么选?Jetson 硬件选型详解【视频讲解】
java·数据库·redis·安全·mybatis
oradh8 小时前
Oracle Undo问题总结(ORA-600 [4xxx] 系列错误)
数据库·oracle
达梦数据8 小时前
DMDRS辅助表生成规则与作用
数据库·oracle
‎ദ്ദിᵔ.˛.ᵔ₎8 小时前
MySQL 表约束
数据库·mysql
Doris__HE8 小时前
【元脑服务器NF5476G7-NF5476M7技术规格分享】
运维·服务器·网络·数据库·性能优化