LeetCode SQL 从入门到精通(MySQL)06(上)

子查询入门,从零理解 Subquery

前面我们已经掌握了各种 JOIN。从本篇开始,我们学习 SQL 中另一项核心能力------子查询(Subquery)。

很多 LeetCode 中等题,都会用到子查询。


一、什么是子查询?

子查询:

一个 SQL 查询嵌套在另一个 SQL 查询里面。

例如:

复制代码
SELECT *
FROM Employee
WHERE salary >
(
    SELECT AVG(salary)
    FROM Employee
);

里面:

复制代码
SELECT AVG(salary)
FROM Employee

就是子查询。

外层 SQL 使用子查询的结果继续筛选。


二、执行顺序

数据库首先执行:

复制代码
SELECT AVG(salary)
FROM Employee;

假设结果:

复制代码
6500

那么整个 SQL 相当于:

复制代码
SELECT *
FROM Employee
WHERE salary > 6500;

所以:

子查询通常先执行,再把结果交给外层查询。


三、返回一个值(标量子查询)

最常见的子查询。

例如:

查询工资最高的人:

复制代码
SELECT *
FROM Employee
WHERE salary=
(
    SELECT MAX(salary)
    FROM Employee
);

里面:

复制代码
MAX(salary)

只返回一个值。

因此:

可以直接比较。


四、返回一列

例如:

复制代码
SELECT *
FROM Orders
WHERE customerId IN
(
    SELECT id
    FROM Customers
    WHERE country='China'
);

子查询:

返回:

复制代码
1
5
8
10

外层:

使用:

复制代码
IN

判断。


五、返回一张表

子查询也可以作为临时表。

例如:

复制代码
SELECT *
FROM
(
    SELECT
        departmentId,
        AVG(salary) avg_salary
    FROM Employee
    GROUP BY departmentId
) t;

这里:

子查询返回:

一张新的结果表。

外层:

把它当普通表继续查询。


六、子查询出现的位置

WHERE

最常见。

复制代码
WHERE salary>
(
    SELECT AVG(salary)
    FROM Employee
)

FROM

作为临时表。

复制代码
FROM
(
    ...
) t

必须起别名。


SELECT

也可以。

例如:

复制代码
SELECT
    name,
    (
        SELECT COUNT(*)
        FROM Orders o
        WHERE o.customerId=c.id
    ) AS order_cnt
FROM Customers c;

不过这种写法效率通常不高。


七、LeetCode 高频题

① 高于平均工资

复制代码
SELECT *
FROM Employee
WHERE salary >
(
    SELECT AVG(salary)
    FROM Employee
);

② 最高工资

复制代码
SELECT *
FROM Employee
WHERE salary=
(
    SELECT MAX(salary)
    FROM Employee
);

③ 某些用户的订单

复制代码
WHERE customerId IN
(
    SELECT ...
)

八、子查询与 JOIN 如何选择?

很多题:

JOIN 和子查询都能完成。

例如:

查询部门平均工资。

可以:

先 GROUP BY。

也可以:

子查询。

原则:

  • 逻辑简单,子查询更容易理解。

  • 多表关联频繁,JOIN 更直观。

  • 实际工作中,两者通常可以互相转换。


九、常见错误

错误一

子查询返回多行,却使用:

复制代码
=

例如:

复制代码
WHERE id=
(
    SELECT id
    FROM ...
)

如果返回多个 id,就会报错。

应该使用:

复制代码
IN

错误二

FROM 子查询忘记别名。

错误:

复制代码
FROM
(
    SELECT ...
)

正确:

复制代码
FROM
(
    SELECT ...
) t

错误三

认为子查询一定慢。

现代数据库优化器会对很多子查询进行优化。

真正决定性能的是:

  • 索引

  • 数据量

  • 执行计划

而不是是否使用子查询。


十、本章总结

今天我们认识了 SQL 中的子查询:

  • 标量子查询(返回一个值)

  • 列子查询(返回一列)

  • 表子查询(返回一张临时表)

理解子查询之后,下一篇我们将学习 LeetCode 高频考点------EXISTS 与 NOT EXISTS,它们是判断数据是否存在的高效工具,也是面试中的经典知识点。

相关推荐
To_OC2 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
long3164 小时前
MySQL 学习练习(配套 01 入门资料)
数据库·学习·mysql
数据库小学妹5 小时前
数据库等保三级和四级有什么区别?从访问控制到备份恢复的完整对比
数据库·安全·数据库安全·三级等保·等保合规·四级等保
隔窗听雨眠6 小时前
AI重塑数据分析:从SQL执行者到智能基础设施构建者
人工智能·sql·数据分析
看浪的路人6 小时前
第3讲:手写第一个 MCP Server(Python SDK)
jvm·数据库·oracle
大眼、不聚光6 小时前
5.mysql--主从同步安装部署
数据库·mysql
Yan_chen6667 小时前
SQL-LABS_Less18-20实战攻略
数据库·sql·web安全·网络安全
oradh7 小时前
Oracle RAC OCR维护操作总结
数据库·oracle·ocr·rac ocr维护·ocr维护·vote disk
snow@li8 小时前
HikariCP:高性能数据库连接池全景深入梳理
java·数据库
一个天蝎座的程序猿8 小时前
传统数据库迁金仓KES,空值问题差点让财务报表翻车
数据库