子查询是嵌套在另一查询中的SELECT语句,用于动态生成条件或数据源。1. 可出现在SELECT、FROM、WHERE、HAVING中,需用括号包裹。2. 常见于WHERE子句,如IN、比较操作符等,示例:查找北京用户的订单。3. 分为非相关子查询(独立执行)和相关子查询(依赖外部查询字段,逐行执行)。4. 注意事项:DML语句中不能直接引用目标表的子查询;深层嵌套影响性能,建议用JOIN替代;使用索引提升效率。合理使用子查询可增强查询灵活性,但需注意语法与性能优化。

在 MySQL 中,子查询(Subquery)是指嵌套在另一个 SQL 查询中的查询语句。它可以出现在 SELECT、FROM、WHERE 或 HAVING 子句中,用来动态生成条件或数据源。掌握子查询能让你更灵活地处理复杂的数据检索需求。
什么是子查询?
子查询就是一个 SELECT 语句,作为另一个查询的一部分运行。外层的查询称为“主查询”,内部的 SELECT 语句就是“子查询”。子查询通常用括号包裹。
示例:
SELECT name FROM users WHERE age > (SELECT AVG(age) FROM users);
这条语句的意思是:找出所有年龄大于平均年龄的用户。其中 (SELECT AVG(age) FROM users) 就是子查询。
子查询的常见使用场景
1. 在 WHERE 子句中使用子查询
这是最常见的用法,用于根据另一个查询的结果来过滤数据。
SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE city = '北京');
查找所有来自“北京”的用户的订单。
注意:IN、NOT IN、=、!=、>、
2. 在 FROM 子句中使用子查询(派生表)
子查询可以作为临时表出现在 FROM 后面,也叫“派生表”或“内联视图”。
SELECT AVG(order_total) FROM (
SELECT user_id, SUM(amount) AS order_total
FROM orders
GROUP BY user_id
) AS user_totals;计算每个用户的订单总额,再求这些总额的平均值。
注意:必须给子查询起一个别名(如 AS user_totals),否则会报错。
3. 在 SELECT 子句中使用标量子查询
子查询返回单个值时,可以在 SELECT 中使用。
SELECT
id,
name,
(SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) AS order_count
FROM users;查询每个用户的信息,并显示其订单数量。
要求:这种子查询必须返回一行一列(即一个值),否则会出错。
子查询的类型
- 标量子查询:返回单个值,常用于 SELECT 或 WHERE 中。
- 行子查询:返回一行多列,可用于比较行数据。
- 列子查询:返回一列多行,常与 IN、ANY、ALL 配合使用。
- 表子查询:返回多行多列,通常用在 FROM 中。
例子:使用 ANY 和 ALL
-- 找出工资高于任意一名销售员的员工 SELECT name, salary FROM employees WHERE salary > ANY (SELECT salary FROM employees WHERE job = 'sales');-- 找出工资高于所有销售员的员工 SELECT name, salary FROM employees WHERE salary > ALL (SELECT salary FROM employees WHERE job = 'sales');
相关子查询 vs 非相关子查询
非相关子查询:子查询可以独立运行,不依赖外部查询。
SELECT * FROM users WHERE age > (SELECT AVG(age) FROM users);
相关子查询:子查询依赖于外部查询的字段,每次主查询处理一行时,子查询都会重新执行。
SELECT u.name, u.age FROM users u WHERE u.age > (SELECT AVG(age) FROM users WHERE city = u.city);
这个查询找出每个城市中年龄高于该城市平均年龄的用户。子查询中的 u.city 来自主查询,因此是相关子查询。
注意事项和性能建议
- 子查询不能直接在 DML 语句(如 UPDATE、DELETE)中引用目标表,会报错 “You can't specify target table for update in FROM clause”。
- 深层嵌套的子查询可能影响性能,建议在大数据量时考虑使用 JOIN 替代。
- 使用索引可以显著提升子查询效率,尤其是 WHERE 或 IN 中涉及的字段。
- 某些情况下,JOIN 比子查询更高效,特别是表连接逻辑清晰时。
基本上就这些。子查询是 MySQL 中非常实用的功能,合理使用可以让查询逻辑更清晰。刚开始可以从小例子入手,逐步尝试复杂嵌套。只要注意语法结构和返回结果的匹配,就能避免大多数错误。










