13.2.10 Subqueries
子查询是另一个语句中的SELECT语句。
支持 SQL 标准要求的所有子查询形式和操作,以及一些特定于 MySQL 的功能。
这是一个子查询的示例:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
在此示例中,SELECT * FROM t1 ...
是外部查询(或* outer statement ),而(SELECT column1 FROM t2)
是 subquery *。我们说子查询在外部查询中是“嵌套”的,实际上,有可能将子查询嵌套在其他子查询中相当深的深度。子查询必须始终出现在括号内。
子查询的主要优点是:
-
它们允许结构化的查询,以便可以隔离语句的每个部分。
-
它们提供了执行操作的替代方法,这些操作原本需要复杂的联接和联合。
-
许多人发现子查询比复杂的联接或联合更具可读性。确实,正是子查询的创新使人们有了将早期 SQL 称为“结构化查询语言”的初衷。
这是一个示例语句,该语句显示有关由 SQL 标准指定并在 MySQL 中受支持的子查询语法的要点:
DELETE FROM t1
WHERE s11 > ANY
(SELECT COUNT(*) /* no hint */ FROM t2
WHERE NOT EXISTS
(SELECT * FROM t3
WHERE ROW(5*t2.s1,77)=
(SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
(SELECT * FROM t5) AS t5)));
子查询可以返回标量(单个值),单行,单列或 table(一个或多个行或一个或多个列)。这些称为标量,列,行和 table 子查询。返回特定类型结果的子查询通常只能在某些上下文中使用,如以下各节所述。
可以在其中使用子查询的语句类型几乎没有限制。子查询可以包含普通SELECT可以包含的许多关键字或子句:DISTINCT
,GROUP BY
,ORDER BY
,LIMIT
,联接,索引提示,UNION构造,Comments,函数等。
子查询的外部语句可以是SELECT,INSERT,UPDATE,DELETE,SET或DO之一。
在 MySQL 中,您无法修改 table 并在子查询中从同一 table 中选择。这适用于诸如DELETE,INSERT,REPLACE,UPDATE和LOAD DATA的语句(因为可以在SET
子句中使用子查询)。
有关优化器如何处理子查询的信息,请参见第 8.2.2 节“优化子查询,派生 table 和视图引用”。有关子查询使用限制的讨论,包括某些形式的子查询语法的性能问题,请参阅第 13.2.10.12 节,“子查询的限制”。