MySQL 8.4 Release Notes
15.2.15.5 行子查询
标量或列子查询返回单个值或多个值。一个 行子查询 是一种子查询变体,它返回单个行,可以返回多个列值。行子查询比较的合法操作符是:
= > < >= <= <> != <=>
以下是两个示例:
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
,查询返回空结果集。表达式是 unknown(即 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节,“行构造函数表达式优化”