UNION 子句
合并多个 SELECT 语句的结果。您也可以在 FROM、WHERE 和 HAVING 子句中包含 UNION。
语法
select‑stmt { UNION [ ALL | DISTINCT ] select-stmt }[...]
[ order-by-clause [ offset-clause ]]
[ limit-clause ]
参数
- select‑stmt
- 返回一行或多行的
SELECT
语句,具体取决于您指定的关键字是 DISTINCT 还是 ALL。以下选项也适用:
-
第一个 SELECT 语句可以包含 LABEL 提示。Vertica 会忽略后续 SELECT 语句中的 LABEL 提示。
-
每个 SELECT 语句都可以指定自己的 ORDER BY、LIMIT 和 OFFSET 子句。包含一个或多个这些子句的 SELECT 语句必须用括号括起来。另请参阅:UNION 中的 ORDER BY、LIMIT 和 OFFSET 子句。
-
DISTINCT | ALL
- 指定是否返回唯一行:
-
DISTINCT(默认)仅返回唯一行。
-
ALL 可连接所有行,包括重复行。为获得最佳性能,请使用 UNION ALL。
-
要求
-
UNION 结果集的所有行都必须存在于至少一个其 SELECT 语句的结果集中。
-
每个 SELECT 语句必须指定相同的列数。
-
对应的 SELECT 语句列的数据类型必须兼容,否则 Vertica 将返回错误。
UNION 中的 ORDER BY、LIMIT 和 OFFSET 子句
UNION 语句可以指定自己的 ORDER BY、LIMIT 和 OFFSET 子句。例如,对于以下示例中描述的表,以下查询将按 emp_name
对 UNION 结果集进行排序,并将输出限制为前两行:
=> SELECT id, emp_name FROM company_a UNION ALL SELECT id, emp_name FROM company_b ORDER BY emp_name LIMIT 2;
id | emp_name
------+----------
5678 | Alice
8765 | Bob
(2 rows)
UNION 子句中的每个 SELECT 语句都可以指定自己的 ORDER BY、LIMIT 和 OFFSET 子句。在这种情况下,SELECT 语句必须用括号括起来。Vertica 首先处理 SELECT 语句的 ORDER BY、LIMIT 和 OFFSET 子句,然后再处理 UNION 子句。
例如,以下 UNION 中的每个 SELECT 语句都指定了自己的 ORDER BY 和 LIMIT 子句。Vertica 处理单个查询,然后连接两个结果集:
=> (SELECT id, emp_name FROM company_a ORDER BY emp_name LIMIT 2)
UNION ALL
(SELECT id, emp_name FROM company_b ORDER BY emp_name LIMIT 2);
id | emp_name
------+-----------
5678 | Alice
9012 | Katherine
8765 | Bob
9012 | Katherine
(4 rows)
以下要求和限制用于确定 Vertica 处理包含 ORDER BY、LIMIT 和 OFFSET 子句的 UNION 子句的方式:
-
UNION 的 ORDER BY 子句必须使用第一个(最左侧的)SELECT 语句指定列。
-
始终将 ORDER BY 子句与 LIMIT 和 OFFSET 一起使用。否则,查询将返回结果集的一个不确定子集。
-
ORDER BY 必须位于 LIMIT 和 OFFSET 之前。
-
当 SELECT 或 UNION 语句同时指定 LIMIT 和 OFFSET 时,Vertica 首先处理 OFFSET 语句,然后将 LIMIT 语句应用于其余行。
非相关子查询中的 UNION
Vertica 支持非相关子查询谓词中的 UNION。例如:
=> SELECT DISTINCT customer_key, customer_name FROM public.customer_dimension WHERE customer_key IN
(SELECT customer_key FROM store.store_sales_fact WHERE sales_dollar_amount > 500
UNION ALL
SELECT customer_key FROM online_sales.online_sales_fact WHERE sales_dollar_amount > 500)
AND customer_state = 'CT';
customer_key | customer_name
--------------+------------------------
7021 | Luigi T. Dobisz
1971 | Betty V. Dobisz
46284 | Ben C. Gauthier
33885 | Tanya Y. Taylor
5449 | Sarah O. Robinson
29059 | Sally Z. Fortin
11200 | Foodhope
15582 | John J. McNulty
24638 | Alexandra F. Jones
...
示例
使用这两个表的示例:
company_a
ID emp_name dept sales
------+------------+-------------+-------
1234 | Stephen | auto parts | 1000
5678 | Alice | auto parts | 2500
9012 | Katherine | floral | 500
company_b
ID emp_name dept sales
------+------------+-------------+-------
4321 | Marvin | home goods | 250
9012 | Katherine | home goods | 500
8765 | Bob | electronics | 20000
从 company_a 和 company_b 中查找所有员工 ID 和姓名
UNION 语句指定选项 DISTINCT,将合并员工的唯一 ID 和姓氏;Katherine 同时为两个公司工作,所以她在结果集中只出现一次。DISTINCT 为默认值,可以忽略:
=> SELECT id, emp_name FROM company_a UNION DISTINCT SELECT id, emp_name FROM company_b ORDER BY id;
id | emp_name
------+-----------
1234 | Stephen
4321 | Marvin
5678 | Alice
8765 | Bob
9012 | Katherine
(5 rows)
下一个 UNION 语句指定选项 ALL。Katherine 同时为两个公司工作,因此查询返回两条与她相关的记录:
=> SELECT id, emp_name FROM company_a UNION ALL SELECT id, emp_name FROM company_b ORDER BY id;
id | emp_name
------+-----------
1234 | Stephen
5678 | Alice
9012 | Katherine
4321 | Marvin
9012 | Katherine
8765 | Bob
(6 rows)
查找每个公司里成绩最好的两名销售人员
每个 SELECT 语句都指定了自己的 ORDER BY 和 LIMIT 子句,因此 UNION 语句将连接每个查询返回的结果集:
=> (SELECT id, emp_name, sales FROM company_a ORDER BY sales DESC LIMIT 2)
UNION ALL
(SELECT id, emp_name, sales FROM company_b ORDER BY sales DESC LIMIT 2);
id | emp_name | sales
------+-----------+-------
8765 | Bob | 20000
5678 | Alice | 2500
1234 | Stephen | 1000
9012 | Katherine | 500
(4 rows)
查找所有员工的销售排序
UNION 语句指定其自己的 ORDER BY 子句,Vertica 将其应用于整个结果:
=> SELECT id, emp_name, sales FROM company_a
UNION
SELECT id, emp_name, sales FROM company_b
ORDER BY sales;
id | emp_name | sales
------+-----------+-------
4321 | Marvin | 250
9012 | Katherine | 500
1234 | Stephen | 1000
5678 | Alice | 2500
8765 | Bob | 20000
(5 rows)
计算各公司各部门的销售总量
每个 SELECT 语句都有自己的 GROUP BY 子句。UNION 将合并每个查询的聚合结果:
=> (SELECT 'Company A' as company, dept, SUM(sales) FROM company_a
GROUP BY dept)
UNION
(SELECT 'Company B' as company, dept, SUM(sales) FROM company_b
GROUP BY dept)
ORDER BY 1;
company | dept | sum
-----------+-------------+-------
Company A | auto parts | 3500
Company A | floral | 500
Company B | electronics | 20000
Company B | home goods | 750
(4 rows)