集运算符

集运算符允许组合多项查询。

本主题内容:

通用语法

[ ( ] <query> [ ) ] { INTERSECT | { MINUS | EXCEPT } | UNION [ ALL ] } [ ( ] <query> [ ) ]
[ ORDER BY ... ]
[ LIMIT ... ]
Copy

一般使用说明

  • 每个查询本身可以包含查询运算符,从而允许任意数量的查询表达式与集运算符相组合。

  • ORDER BYLIMIT / FETCH 子句应用于集运算符的结果。

  • 使用这些运算符时:

    • 确保每个查询均选择相同数量的列。

    • 确保在来自不同源的行之间,每列的数据类型均保持一致。在下面的 示例 部分中,一个示例说明了数据类型不匹配时的潜在问题和解决方案。

    • 通常,列的“含义”及数据类型应该匹配。以下内容不会产生预期结果:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName, LastName FROM contractors;
      
      Copy

      使用星号指定表的所有列时,出错风险会增加,例如:

      SELECT * FROM table1
      UNION ALL
      SELECT * FROM table2;
      
      Copy

      如果表的列数相同,但列的顺序不同,查询结果有可能不正确。

    • 输出列的名称基于第一个查询的列名称。例如,以下查询:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName, LastName FROM contractors;
      
      Copy

      其行为类似于以下查询:

      SELECT LastName, FirstName FROM employees
      UNION ALL
      SELECT FirstName AS LastName, LastName AS FirstName FROM contractors;
      
      Copy
  • 集运算符的优先级与 ANSI 和 ISO SQL 标准相符:

    • UNION [ALL]MINUS (EXCEPT) 运算符具有同等优先级。

    • INTERSECT 运算符的优先级高于 UNION [ALL]MINUS (EXCEPT)。

    优先级相同的运算符按照从左到右的顺序进行处理。

    您可以使用括号来强制改变表达式的计算顺序。

    并非所有数据库供应商均遵循 ANSI/ISO 标准来确定集运算符的优先级。Snowflake 建议使用括号来指定计算顺序,尤其是在将代码从其他供应商移植到 Snowflake 时,或者是编写可能在其他数据库和 Snowflake 上执行的代码时。

INTERSECT

返回一个查询的结果集中同样出现在另一个查询的结果集中的行,并消除重复项。

语法

SELECT ...
INTERSECT
SELECT ...
Copy

MINUS、EXCEPT

在一个查询的结果集中移除出现在另一个查询的结果集中的行,并消除重复项。

MINUS 和 EXCEPT 关键字具有相同含义,可以互换使用。

语法

SELECT ...
MINUS
SELECT ...

SELECT ...
EXCEPT
SELECT ...
Copy

UNION [ ALL ]

合并两个查询的结果集:

  • UNION 执行合并并消除重复项。

  • UNION ALL 执行合并,但不消除重复项。

默认值为 UNION (即消除重复项)。

语法

SELECT ...
UNION [ ALL ]
SELECT ...
Copy

示例

此示例演示了 UNION 运算符的基本用法。它还演示了数据类型不匹配时的潜在问题,随后提供了解决方案。

首先创建表并插入一些数据:

CREATE TABLE t1 (v VARCHAR);
CREATE TABLE t2 (i INTEGER);
INSERT INTO t1 (v) VALUES ('Adams, Douglas');
INSERT INTO t2 (i) VALUES (42);
Copy

执行涉及不同数据类型的 UNION 操作:

SELECT v FROM t1    -- VARCHAR
UNION
SELECT i FROM t2    -- INTEGER
;
Copy

输出:

100038 (22018): Numeric value 'Adams, Douglas' is not recognized
Copy

现在使用显式类型转换,将输入转换为兼容类型:

SELECT v::VARCHAR FROM t1
UNION
SELECT i::VARCHAR FROM t2;
Copy

输出:

+----------------+
| V::VARCHAR     |
|----------------|
| Adams, Douglas |
| 42             |
+----------------+
Copy
语言: 中文