MySQL 8.3 Release Notes
标量或列子查询返回单个值或一列值。一个 行子查询 是一种子查询变体,它返回单行,因此可以返回多个列值。合法的行子查询比较运算符是:
= > < >= <= <> != <=>
以下是两个示例:
SELECT * FROM t1
WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);
SELECT * FROM t1
WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);
对于这两个查询,如果表 t2
包含一个单行,其中 id = 10
,则子查询返回单行。如果该行的 col3
和 col4
值等于 t1
中的任何行的 col1
和 col2
值,则 WHERE
表达式为 TRUE
,每个查询将返回这些 t1
行。如果 t2
行的 col3
和 col4
值不等于 t1
中的任何行的 col1
和 col2
值,则表达式为 FALSE
,查询将返回空结果集。如果子查询不产生行,则表达式为 未知(即 NULL
)。如果子查询产生多行,因为行子查询只能返回最多一行,因此会出现错误。
有关每个运算符如何在行比较中工作的信息,请参阅 第 14.4.2 节,“比较函数和运算符”。
表达式 (1,2)
和 ROW(1,2)
有时称为 行构造函数。这两个是等效的。行构造函数和子查询返回的行必须包含相同数量的值。
行构造函数用于与返回两个或多个列的子查询进行比较。当子查询返回单个列时,这将被视为标量值,而不是行,因此不能与不返回至少两个列的子查询一起使用。因此,以下查询将因语法错误而失败:
SELECT * FROM t1 WHERE ROW(1) = (SELECT column1 FROM t2)
行构造函数在其他上下文中是合法的。例如,以下两个语句是语义等效的(并且由优化器以相同的方式处理):
SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
以下查询回答了请求:“在表 t1
中查找所有也存在于表 t2
中的行”:
SELECT column1,column2,column3
FROM t1
WHERE (column1,column2,column3) IN
(SELECT column1,column2,column3 FROM t2);
有关优化器和行构造函数的更多信息,请参阅 第 10.2.1.22 节,“行构造函数表达式优化”