UNION 子句

合并多个 SELECT 语句的结果。您也可以在 FROMWHEREHAVING 子句中包含 UNION。

语法

select‑stmt { UNION [ ALL | DISTINCT ] select-stmt }[...]
    [ order-by-clause  [ offset-clause ]]
    [ limit-clause ]

参数

select‑stmt
返回一行或多行的 SELECT 语句,具体取决于您指定的关键字是 DISTINCT 还是 ALL。

以下选项也适用:

DISTINCT | ALL
指定是否返回唯一行:
  • DISTINCT(默认)仅返回唯一行。

  • ALL 可连接所有行,包括重复行。为获得最佳性能,请使用 UNION ALL。

要求

  • UNION 结果集的所有行都必须存在于至少一个其 SELECT 语句的结果集中。

  • 每个 SELECT 语句必须指定相同的列数。

  • 对应的 SELECT 语句列的数据类型必须兼容,否则 Vertica 将返回错误。

UNION 中的 ORDER BY、LIMIT 和 OFFSET 子句

UNION 语句可以指定自己的 ORDER BYLIMITOFFSET 子句。例如,对于以下示例中描述的表,以下查询将按 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 BYLIMITOFFSET 子句的 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)

另请参阅