7.4. 合并查询 (UNION, INTERSECT, EXCEPT) #

可以使用集合操作 union、intersection 和 difference 来合并两个查询的结果。语法如下:

query1 UNION [ALL] query2
query1 INTERSECT [ALL] query2
query1 EXCEPT [ALL] query2

其中 query1 和 query2 是可以利用到目前为止讨论过的任何特性的查询。

UNION 会将 query2 的结果附加到 query1 的结果之后(尽管不保证行实际返回的顺序)。此外,它会从结果中删除重复行,方式与 DISTINCT 相同,除非使用了 UNION ALL。

INTERSECT 返回 query1 的结果集和 query2 的结果集中都存在的行。除非使用了 INTERSECT ALL,否则会删除重复行。

EXCEPT 返回 query1 的结果集中存在但 query2 的结果集中不存在的行。(有时也称为两个查询的差集。)同样,除非使用了 EXCEPT ALL,否则会删除重复行。

为了计算两个查询的 union、intersection 或 difference,这两个查询必须是“union 兼容”,这意味着它们返回的列数相同,并且对应列的数据类型兼容,具体描述参见10.5 节。

集合操作可以合并,例如:

query1 UNION query2 EXCEPT query3

这等同于:

(query1 UNION query2) EXCEPT query3

如这里所示,您可以使用括号来控制求值顺序。没有括号时,UNION 和 EXCEPT 是从左到右结合的,但 INTERSECT 的优先级高于这两个操作符。因此:

query1 UNION query2 INTERSECT query3

意味着:

query1 UNION (query2 INTERSECT query3)

您也可以用括号将单个 query 括起来。如果 query 需要使用后面章节讨论的任何子句,例如 LIMIT,这一点就很重要。没有括号,您会遇到语法错误,或者该子句将被理解为应用于集合操作的输出而不是其输入之一。例如:

SELECT a FROM b UNION SELECT x FROM y LIMIT 10

是可以接受的,但它的意思是:

(SELECT a FROM b UNION SELECT x FROM y) LIMIT 10

而不是:

SELECT a FROM b UNION (SELECT x FROM y LIMIT 10)