子查询是一个 SELECT
语句在另一个语句中。
所有子查询形式和操作都支持 SQL 标准所需的功能,以及一些 MySQL 特有的功能。
下面是一个子查询的示例:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
在这个示例中, SELECT * FROM t1 ...
是 外部查询(或 外部语句),而 (SELECT column1 FROM t2)
是 子查询。我们说子查询是 嵌套 在外部查询中,并且实际上可以将子查询嵌套在其他子查询中,达到相当深的深度。子查询必须始终出现在括号中。
子查询的主要优点是:
-
它们允许查询 结构化,以便隔离语句的每个部分。
-
它们提供了替代复杂连接和联合操作的方法。
-
许多人发现子查询比复杂的连接或联合操作更易读。实际上,这正是人们最初将早期 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)));
子查询可以返回标量(单个值)、单行、单列或表(一个或多个行的一个或多个列)。这些被称为标量、列、行和表子查询。返回特定类型结果的子查询通常只能在特定上下文中使用,如下一节所述。
几乎没有限制子查询可以在哪些语句中使用。子查询可以包含许多普通 SELECT
可以包含的关键字或子句:DISTINCT
、GROUP BY
、ORDER BY
、LIMIT
、连接、索引提示、UNION
构造、注释、函数等等。
表
和 VALUES
语句可以在子查询中使用。使用 VALUES
的子查询通常是使用集合符号或 SELECT
或 表
语法更紧凑的版本;假设表 ts
是使用语句 CREATE TABLE ts VALUES ROW(2), ROW(4), ROW(6)
创建的,那么以下语句都是等效的:
SELECT * FROM tt
WHERE b > ANY (VALUES ROW(2), ROW(4), ROW(6));
SELECT * FROM tt
WHERE b > ANY (SELECT * FROM ts);
SELECT * FROM tt
WHERE b > ANY (TABLE ts);
以下部分将展示 表
子查询的示例。
子查询的外部语句可以是: SELECT
、 INSERT
、 UPDATE
、 DELETE
、 SET
或 DO
。
关于优化器如何处理子查询的信息,请参阅 第 10.2.2 节,“优化子查询、派生表、视图引用和公共表表达式”。关于子查询使用的限制,包括某些子查询语法形式的性能问题,请参阅 第 15.2.15.12 节,“子查询限制”。