

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 集合运算符
<a name="UNION"></a>

*集合运算符*用于比较和合并两个独立查询表达式的结果。

AWS Clean Rooms Spark SQL 支持下表中列出的以下集合运算符。


| 设置运算符  | 
| --- | 
| INTERSECT | 
| 全部相交 | 
| EXCEPT | 
| 除了全部 | 
| 联合 | 
| UNION ALL | 

例如，如果您希望知道网站的哪些用户既是买家又是卖家且其用户名存储在单独的列或表中，则可查找这两类用户的*交集*。如果您希望知道哪些网站用户是买家而不是卖家，则可使用 EXCEPT 运算符查找这两个用户列表的*差集*。如果您希望构建一个所有用户的列表（无论角色如何），则可使用 UNION 运算符。

**注意**  
ORDER BY、LIMIT、SELECT TOP 和 OFFSET 子句不能用在 UNION、UNION ALL、INTERSECT 和 EXCEPT 集合运算符合并的查询表达式中。

**Topics**
+ [语法](#UNION-synopsis)
+ [参数](#UNION-parameters)
+ [集合运算符的计算顺序](#UNION-order-of-evaluation-for-set-operators)
+ [使用说明](#UNION-usage-notes)
+ [示例 UNION 查询](example_union_query.md)
+ [示例 UNION ALL 查询](example_unionall_query.md)
+ [示例 INTERSECT 查询](example_intersect_query.md)
+ [示例 EXCEPT 查询](Example_EXCEPT_query.md)

## 语法
<a name="UNION-synopsis"></a>

```
subquery1
{ { UNION [ ALL | DISTINCT ] |
              INTERSECT [ ALL | DISTINCT ] |
              EXCEPT [ ALL | DISTINCT ] } subquery2 } [...] }
```

## 参数
<a name="UNION-parameters"></a>

 *subquery1，subquery2*   
一种查询表达式，以其选择列表的形式对应于 UNION、UNION ALL、INTERSECT、INTERSECT ALL、EXCEPT 或 EXCEPT ALL 运算符之后的第二个查询表达式。这两个表达式必须包含数量相同并且数据类型兼容的输出列；否则，无法比较和合并两个结果集。集合运算不允许在不同类别的数据类型之间进行隐式转换。有关更多信息，请参阅 [类型兼容性和转换](s_Type_conversion.md)。  
您可以构建包含无限数量的查询表达式并任意组合使用 UNION、INTERSECT 和 EXCEPT 运算符来将这些表达式链接起来的查询。例如，假定表 T1、T2 和 T3 包含兼容的列集，则以下查询结构是有效的：  

```
select * from t1
union
select * from t2
except
select * from t3
```

联合 [全部 \| 不同]  
从两个查询表达式返回行的集合运算，无论行派生自一个查询表达式还是两个查询表达式。

相交 [全部 \| 不同]  
返回派生自两个查询表达式的行的集合运算。将丢弃未同时由两个表达式返回的行。

除了 [全部 \| 不同]  
返回派生自两个查询表达式之一的行的集合运算。要符合结果的要求，行必须存在于第一个结果表而不存在于第二个结果表中。  
EXCEPT ALL 不会从结果行中删除重复项。  
MINUS 和 EXCEPT 完全同义。

## 集合运算符的计算顺序
<a name="UNION-order-of-evaluation-for-set-operators"></a>

UNION 和 EXCEPT 集合运算符是左关联的。如果未指定圆括号来影响优先顺序，则将以从左到右的顺序来计算这些集合运算符的组合。例如，在以下查询中，首先计算 T1 和 T2 的 UNION，然后对 UNION 结果执行 EXCEPT 操作：

```
select * from t1
union
select * from t2
except
select * from t3
```

在同一个查询中使用运算符组合时，INTERSECT 运算符优先于 UNION 和 EXCEPT 运算符。例如，以下查询将计算 T2 和 T3 的交集，然后计算得到的结果与 T1 的并集：

```
select * from t1
union
select * from t2
intersect
select * from t3
```

通过添加圆括号，可以强制实施不同的计算顺序。在以下示例中，将 T1 和 T2 的并集结果与 T3 执行交集运算，并且查询可能会生成不同的结果。

```
(select * from t1
union
select * from t2)
intersect
(select * from t3)
```

## 使用说明
<a name="UNION-usage-notes"></a>
+ 集合运算查询结果中返回的列名是来自第一个查询表达式中的表的列名（或别名）。由于这些列名可能会造成误解（因为列中的值派生自位于集合运算符任一侧的表），您可能需要为结果集提供有意义的别名。
+ 当集合运算符查询返回小数结果时，将提升对应的结果列以返回相同的精度和小数位数。例如，在以下查询中，T1.REVENUE 为 DECIMAL(10,2) 列而 T2.REVENUE 为 DECIMAL(8,4) 列，小数结果将提升为 DECIMAL(12,4)：

  ```
  select t1.revenue union select t2.revenue;
  ```

  小数位数为 `4`，因为这是两个列的最大小数位数。精度为 `12`，因为 T1.REVENUE 要求小数点左侧有 8 位数 (12 - 4 = 8)。此类提升可确保 UNION 两侧的所有值都适合结果。对于 64 位值，最大结果精度为 19，最大结果小数位数为 18。对于 128 位值，最大结果精度为 38，最大结果小数位数为 37。

  如果生成的数据类型超过 AWS Clean Rooms 精度和小数位数限制，则查询将返回错误。
+ 对于集合运算，如果对于每个相应的列对，两个数据值*相等* 或*都为 NULL*，则两个行将被视为相同。例如，如果表 T1 和 T2 都包含一列和一行，并且两个表中的行都为 NULL，则对这两个表执行的 INTERSECT 运算将返回该行。