LanguageManual Union

Union Syntax

select_statement UNION [ALL | DISTINCT] select_statement UNION [ALL | DISTINCT] select_statement ...

UNION 用于将来自多个 SELECT 语句的结果合并为一个结果集。

  • 1.2.0之前的 Hive 版本仅支持 UNION ALL(袋联合),其中不会消除重复的行。

  • 在 Hive 1.2.0和更高版本中,UNION 的默认行为是从结果中删除重复的行。可选的 DISTINCT 关键字除了默认关键字外没有其他作用,因为它还指定了重复行删除。使用可选的 ALL 关键字时,不会发生重复行删除,并且结果包括所有 SELECT 语句中的所有匹配行。

您可以在同一查询中混合使用 UNION ALL 和 UNION DISTINCT。处理混合的 UNION 类型,以使 DISTINCT 联合覆盖其左侧的所有 ALL 联合。可以使用 UNION DISTINCT 显式地生成 DISTINCT 联合,也可以使用 UNION 隐式地生成,而无需后面的 DISTINCT 或 ALL 关键字。

每个* select_statement *返回的列的数量和名称必须相同。否则,将引发架构错误。

FROM 子句中的 UNION

如果必须对 UNION 的结果进行一些其他处理,则可以将整个语句表达式嵌入到 FROM 子句中,如下所示:

SELECT *
FROM (
  select_statement
  UNION ALL
  select_statement
) unionResult

例如,如果我们假设有两个不同的表来跟踪哪个用户发布了视频并且哪个用户发布了 Comment,则以下查询将 UNION ALL 的结果与 user 表结合在一起,以为所有用户创建一个带 Comments 的流视频发布和 Comment 发布事件:

SELECT u.id, actions.date
    FROM (
        SELECT av.uid AS uid 
        FROM action_video av 
        WHERE av.date = '2008-06-03' 
        UNION ALL 
        SELECT ac.uid AS uid 
        FROM action_comment ac 
        WHERE ac.date = '2008-06-03' 
     ) actions JOIN users u ON (u.id = actions.uid)

DDL 中的并集和插入语句

可以在视图,插入和 CTAS(将表创建为 select)语句中使用并集。一个查询可以包含多个 UNION 子句,如上面的syntax所示。

Applying Subclauses

要将 ORDER BY,SORT BY,CLUSTER BY,DISTRIBUTE BY 或 LIMIT 应用于单个 SELECT,请将子句放在括住 SELECT 的括号内:

SELECT key FROM (SELECT key FROM src ORDER BY key LIMIT 10)subq1
UNION
SELECT key FROM (SELECT key FROM src1 ORDER BY key LIMIT 10)subq2

要将 ORDER BY,SORT BY,CLUSTER BY,DISTRIBUTE BY 或 LIMIT 子句应用于整个 UNION 结果,请将 ORDER BY,SORT BY,CLUSTER BY,DISTRIBUTE BY 或 LIMIT 放在最后一个之后。下面的示例同时使用 ORDER BY 和 LIMIT 子句:

SELECT key FROM src
UNION
SELECT key FROM src1
ORDER BY key LIMIT 10

模式匹配的列别名

UNION 在表达式列表的两侧都希望有相同的架构。结果,以下查询可能会失败,并显示一条错误消息,例如“ FAILED:SemanticException 4:47 联合双方的模式都应匹配”。

INSERT OVERWRITE TABLE target_table
  SELECT name, id, category FROM source_table_1
  UNION ALL
  SELECT name, id, "Category159" FROM source_table_2

在这种情况下,列别名可用于强制使用相等的架构:

INSERT OVERWRITE TABLE target_table
  SELECT name, id, category FROM source_table_1
  UNION ALL
  SELECT name, id, "Category159" as category FROM source_table_2

列类型转换

在版本 2.2.0 中的HIVE-14251之前,Hive 尝试跨 Hive 类型组执行隐式转换。更改HIVE-14251,Hive 将仅在每个类型组(包括字符串组,数字组或日期组)内执行隐式转换,而不跨组执行隐式转换。为了合并来自不同组的类型,例如字符串类型和日期类型,在查询中需要从字符串到日期或从日期到字符串的显式转换。

SELECT name, id, cast('2001-01-01' as date) d FROM source_table_1
  UNION ALL
  SELECT name, id, hiredate as d FROM source_table_2

Version Information

Version information

在 Hive 0.12.0 和更早版本中,联合只能在子查询中使用,例如“ SELECT * FROM(* select_statement * UNION ALL * select_statement * UNION ALL ...)* unionResult *”。

从 Hive 0.13.0 开始,联合还可以在顶级查询中使用:“ * select_statement * UNION ALL * select_statement * UNION ALL ...”。 (请参阅HIVE-6189。)

在 Hive 1.2.0 之前,仅支持 UNION ALL(袋子联合)。从 Hive 1.2.0 开始支持 UNION(或 UNION DISTINCT)。 (请参阅HIVE-9039。)