13.2.10.5 行子查询

标量或列子查询返回单个值或一列值。 * row subquery *是一个子查询变量,它返回单行,因此可以返回多个列值。行子查询比较的合法运算符为:

=  >  <  >=  <=  <>  !=  <=>

这是两个示例:

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);

对于这两个查询,如果 tablet2包含带有id = 10的单行,则子查询将返回单行。如果此行的col3col4值等于t1中任何行的col1col2值,则WHEREtable 达式为TRUE,并且每个查询都返回那些t1行。如果t2col3col4的值不等于任何t1行的col1col2的值,则 table 达式为FALSE且查询返回空结果集。如果子查询不产生任何行,则 table 达式为* unknown *(即NULL)。如果子查询产生多行,则会发生错误,因为一行子查询最多可以返回一行。

有关每个运算符如何进行行比较的信息,请参见第 12.3.2 节“比较函数和运算符”

table 达式(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;

以下查询回答了该请求:“在 tablet1中查找 tablet2中也存在的所有行”:

SELECT column1,column2,column3
  FROM t1
  WHERE (column1,column2,column3) IN
         (SELECT column1,column2,column3 FROM t2);

有关优化器和行构造器的更多信息,请参见第 8.2.1.19 节,“行构造器 table 达式优化”