MySQL 子查询

17 Mar 2025 | 6 分钟阅读

MySQL 中的子查询是嵌套在另一个 SQL 查询中的查询,并与 SELECT、INSERT、UPDATE 或 DELETE 语句以及各种运算符一起嵌入。我们还可以将子查询嵌套在另一个子查询中。子查询被称为内部查询,而包含子查询的查询被称为外部查询。内部查询首先执行,将结果提供给外部查询,然后执行主/外部查询。MySQL 允许我们在任何地方使用子查询,但它必须用括号括起来。SQL 标准支持的所有子查询形式和操作在 MySQL 中也受支持。

以下是使用子查询的规则

  • 子查询应始终使用括号
  • 如果主查询没有子查询的多个列,那么子查询在 SELECT 命令中只能有一列。
  • 我们可以将各种比较运算符与子查询一起使用,例如 >、<、=、IN、ANY、SOME 和 ALL。当子查询返回多行时,多行运算符非常有用。
  • 我们不能在子查询中使用 ORDER BY 子句,尽管它可以在主查询中使用。
  • 如果我们在集合函数中使用子查询,它不能立即被集合函数括起来。

以下是使用子查询的优点

  • 子查询使查询具有结构化形式,允许我们隔离语句的每个部分。
  • 子查询提供了从表中查询数据的替代方法;否则,我们需要使用复杂的连接和联合。
  • 子查询比复杂的连接或联合语句更具可读性。

MySQL 子查询语法

以下是在 MySQL 中使用子查询的基本语法

MySQL 子查询示例

让我们通过一个例子来理解它。假设我们有一个名为 "employees" 的表,其中包含以下数据

表:employees

MySQL Subquery

以下是一个简单的 SQL 语句,它返回员工 ID 与子查询匹配的员工详细信息

此查询将返回以下输出

MySQL Subquery

带有比较运算符的 MySQL 子查询

比较运算符是用于比较值并返回结果(真或假)的运算符。MySQL 中使用的比较运算符有 <、>、=、<>、<=> 等。我们可以在返回单个值的比较运算符之前或之后使用子查询。返回的值可以是算术表达式或列函数。之后,SQL 会将子查询结果与比较运算符另一侧的值进行比较。下面的示例更清楚地解释了这一点

以下是一个简单的 SQL 语句,它借助子查询返回收入超过 350000 的员工详细信息

此查询首先执行子查询,该子查询返回收入 > 350000 的员工 ID。其次,主查询将返回员工 ID 在子查询返回的结果集中的所有员工详细信息。

执行语句后,我们将得到如下输出,其中我们可以看到收入 > 350000 的员工详细信息。

MySQL Subquery

让我们看一个使用另一个比较运算符(例如等号 (=))来查找使用子查询收入最高的员工详细信息的示例。

它将给出输出,其中我们可以看到两位收入最高的员工的详细信息。

MySQL Subquery

带有 IN 或 NOT-IN 运算符的 MySQL 子查询

如果子查询生成多个值,我们需要在 WHERE 子句中使用 IN 或 NOT IN 运算符。假设我们有一个名为 "Student""Student2" 的表,其中包含以下数据

表:Student

MySQL Subquery

表:Student2

MySQL Subquery

以下带有 NOT IN 运算符的子查询返回不属于洛杉矶市的学生详细信息,如下所示

执行后,我们可以看到结果包含不属于洛杉矶市的学生详细信息。

MySQL Subquery

FROM 子句中的 MySQL 子查询

如果我们在 FROM 子句中使用子查询,MySQL 将把子查询的输出用作临时表。我们称此表为派生表、内联视图或物化子查询。

以下子查询返回订单表中的最大、最小和平均项目数

它将给出如下输出

MySQL Subquery

MySQL 相关子查询

MySQL 中的相关子查询是一个依赖于外部查询的子查询。它使用来自外部查询的数据或包含对父查询的引用,该父查询也出现在外部查询中。MySQL 对外部查询中的每一行评估一次。

在上面的查询中,我们选择员工姓名和城市,其收入高于每个城市所有员工的平均收入。

MySQL Subquery

子查询针对指定表的每个城市执行,因为它会随每一行而变化。因此,平均收入也会改变。然后,主查询过滤收入高于子查询平均收入的员工详细信息。

带有 EXISTS 或 NOT EXISTS 的 MySQL 子查询

EXISTS 运算符是一个布尔运算符,它返回真或假结果。它与子查询一起使用,并检查子查询中数据的存在性。如果子查询返回任何记录,此运算符返回真。否则,它将返回假。NOT EXISTS 运算符用于否定,当子查询不返回任何行时,它返回真值。否则,它返回假。EXISTS 和 NOT EXISTS 都与相关子查询一起使用。以下示例更清楚地说明了这一点。假设我们有一个表 customer 和 order,其中包含如下数据

MySQL Subquery

以下 SQL 语句使用 EXISTS 运算符查找至少下了一个订单的客户的姓名、职业和年龄。

此语句使用 NOT EXISTS 运算符,它返回未下订单的客户详细信息。

我们可以看到下面的输出以理解上述查询结果。

MySQL Subquery

要阅读有关 EXISTS 运算符的更多信息,请单击此处

MySQL 行子查询

它是一个返回单行子查询,其中我们可以获得多个列值。我们可以使用以下运算符来比较行子查询:=、>、<、>=、<=、<>、!=、<=>。让我们看以下示例

如果给定行的 cust_id、occupation 值等于第一个表中任何行的 order_id、order_date 值,则 WHERE 表达式为 TRUE,并且每个查询返回那些第一个表行。否则,表达式为 FALSE,并且查询生成一个空集,如下图所示

MySQL Subquery

带有 ALL、ANY 和 SOME 的 MySQL 子查询

我们可以在比较运算符之后使用子查询,后跟关键字 ALL、ANY 或 SOME。以下是使用带有 ALL、ANY 或 SOME 的子查询的语法

ALL 关键字将值与子查询返回的值进行比较。因此,如果比较对于子查询返回的所有值都为 TRUE,则返回 TRUE。ANY 关键字如果比较对于子查询返回的任何值都为 TRUE,则返回 TRUE。ANY 和 SOME 关键字是相同的,因为它们是彼此的别名。以下示例更清楚地解释了这一点

我们将得到如下输出

MySQL Subquery

如果我们将 ALL 替换为 ANY,则当比较对于子查询返回的列中的所有值都为 TRUE 时,它将返回 TRUE。例如

我们可以看到如下输出

MySQL Subquery
下一主题MySQL 派生表