8.4. 组合查询

两个查询的结果可以用集合操作并、交、差进行组合。语法是

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

其中query1query2是可以使用到目前为止讨论的任何功能的查询。

UNION有效地把query2的结果附加到query1的结果上(不过我们不能保证这就是这些行实际被返回的顺序)。此外,它将删除结果中所有重复的行, 就象DISTINCT做的那样,除非你使用了UNION ALL

INTERSECT返回那些同时存在于query1query2的结果中的行,除非声明了INTERSECT ALL, 否则所有重复行都被消除。

EXCEPT返回所有在query1的结果中但是不在query2的结果中的行(有时侯这叫做两个查询的)。同样的,除非声明了EXCEPT ALL,否则所有重复行都被消除。

为了计算两个查询的并、交、差,这两个查询必须是并操作兼容的,也就意味着它们都返回同样数量的列, 并且对应的列有兼容的数据类型,如Section 11.5中描述的那样。

可以组合使用集合操作,例如

query1 UNION query2 EXCEPT query3

它等价于

(query1 UNION query2) EXCEPT query3

如此所示,您可以使用括号来控制评估顺序。 没有括号,UNIONEXCEPT从左到右关联, 但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)