MySQL 子查询与嵌套查询

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/

截止目前, 星球 内专栏累计输出 66w+ 字,讲解图 2896+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2300+ 小伙伴加入学习 ,欢迎点击围观

子查询(Subquery)是 MySQL 中一种强大的查询方式,允许在一个查询中嵌套另一个查询。通过子查询,我们可以将复杂的问题分解成简单的部分,逐步求解。


什么是子查询?

子查询是一个嵌套在另一个 SQL 查询中的查询,其结果可以被外部查询使用。

子查询通常出现在以下位置:

  • SELECT 子句
  • FROM 子句
  • WHERE 子句

子查询的基本语法

SELECT 列名1, 列名2
FROM 表名
WHERE 列名 IN (
    SELECT 列名
    FROM 另一表
    WHERE 条件
);

子查询的分类

1. 单行子查询

返回单个值(一个行一个列)的子查询。

示例:查找分数最高的学生姓名

SELECT name 
FROM t_student 
WHERE score = (
    SELECT MAX(score) FROM t_student
);

2. 多行子查询

返回多行数据的子查询,常与 INEXISTS 一起使用。

示例:查找分数高于班级平均分的学生

SELECT name 
FROM t_student 
WHERE score > (
    SELECT AVG(score) 
    FROM t_student
);

3. 嵌套子查询

子查询嵌套在另一个子查询中。

示例:查询最低分的学生姓名

SELECT name 
FROM t_student 
WHERE score = (
    SELECT MIN(score) 
    FROM t_student 
    WHERE score > (
        SELECT AVG(score) 
        FROM t_student
    )
);

子查询的使用位置

1. 在 SELECT 中使用子查询

为每位学生添加班级的平均分作为新列。

SELECT name, 
       score, 
       (SELECT AVG(score) 
        FROM t_student 
        WHERE class_id = s.class_id) AS avg_class_score
FROM t_student AS s;

2. 在 FROM 中使用子查询

将子查询作为一个临时表(派生表)使用。

SELECT class_id, MAX(avg_score) AS highest_avg
FROM (
    SELECT class_id, AVG(score) AS avg_score
    FROM t_student
    GROUP BY class_id
) AS class_avg;

3. 在 WHERE 中使用子查询

查询所有在指定课程中成绩高于 80 分的学生。

SELECT name 
FROM t_student
WHERE student_id IN (
    SELECT student_id
    FROM t_score
    WHERE course_id = 101 AND score > 80
);

子查询的限制与注意事项

  1. 性能问题

    • 子查询可能会导致性能下降,尤其是嵌套较深时。优化方法包括:
      • 使用 JOIN 替代部分子查询。
      • 利用索引提升查询速度。
  2. 子查询的限制

    • 子查询不能直接在 LIMITORDER BY 中使用。
  3. 相关子查询
    相关子查询会依赖于外部查询的结果,执行效率可能较低。


子查询和 JOIN 的对比

特性子查询JOIN
可读性简单的子查询易读复杂查询中,JOIN 更清晰
性能子查询通常性能较差JOIN 通常效率更高
使用场景适合单次逻辑处理适合大数据量关联查询

小结

  • 子查询是嵌套在其他查询中的查询,用于简化复杂查询问题。
  • 常见的子查询类型包括单行子查询、多行子查询和嵌套子查询。
  • 子查询可以出现在 SELECTFROMWHERE 等位置。
  • 在性能要求较高的场景下,需谨慎使用子查询,并考虑优化策略。

通过掌握子查询与嵌套查询,你可以轻松应对复杂的业务需求。