Hive语法:union

Hive语法:union

1、介绍

本文参考官方介绍,原文地址以下: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Unionsql

Hive官方提供了一种联合查询的语法,原名为Union Syntax,用于联合两个表的记录进行查询,此处的联合和join是不一样的,join是将两个表的字段拼接到一块儿,而union是将两个表的记录拼接在一块儿。apache

通俗来说,join是用于左右拼接,而union是用于上下拼接。架构

好比有以下两个表: 表1:ide

id username
1 user001
2 user002

表2:测试

id username
1 user003
2 user004

join的左右拼接如这样:ui

id username id username
1 user001 1 user003
2 user002 2 user004

unoin的上下拼接如这样:.net

id username
1 user001
2 user002
1 user003
2 user004

2、语法

官方语法:code

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

union用于将多个select语句的结果组合到单个结果集中。orm

须要注意:blog

  • 1.2.0以前的Hive版本仅支持union all,其中不会删除重复行。
  • 在Hive1.2.0##及更高版本中,union的默认行为是从结果中删除重复的行。可选的distinct关键字指定了删除重复行。使用可选的all关键字,不会发生重复行删除,结果包含select语句中的全部匹配行。
  • 能够在同一查询中混合使用union all和union distinct。
  • 每一个select语句返回的列的数量和名称必须相同,不然,将引起架构错误。错误内容以下:SemanticException Schema of both sides of union should match.

3、应用

一、from子句

union语句能够做为form的子句进行使用,简单示例以下:

select * form ( select_statement union all select_statement ) unionResult

以下是官方示例:

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和插入语句

union能够在视图,插入和CTAS(create table as select)语句中使用。查询能够包含多个union子句。

三、应用于从句

要将order by,sort by,cluster by,distribute by 或limit 应用于union两边的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

要将以上应用于union以后的最终结果也是能够的,示例以下:

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

四、字段别名应用

union要求表达式两侧的字段名称以及字段数量都必须相同,这种状况下,有些表字段的含义相等,可是字段名称不一样的状况,使用union就会出现报错。union支持字段别名相等。

以下示例:

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

上述语句可正常执行。

五、字段类型转换

Hive2.2.0版本的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

4、案例

本人本身寻找了一个使用此语法的案例,这里和你们进行分享。若有错误敬请指正。

一、要求

存在两张用户表,一张为历史表,一张为当日表,天天要将当日表中的数据和历史表中的数据进行去重合并到新的历史表中。

二、思路

这里本人首先想到的步骤是,将两张表的数据进行合并,而后查询全部去重存入另一张表。 这个思路的实现局限于hive的版本,这里提供两个版本的,两种方式进行实现,更高的2.2.0版本,本人没有使用,这里使用的两个版本分别是CDH中集成的hive1.1.0版本和开源的hive1.2.0版本。

三、准备

建立三张表:

  • user01:表明历史表
  • user02:表明当日表
  • user03:表明最后合并的历史表。

建表语句:

create external table user01(id int, username string) row format delimited fields terminated by '|' location 'hdfs://192.168.75.150:9000/test/user1';

create external table user02(id int,username string) row format delimited fields terminated by '|' location 'hdfs://192.168.75.150:9000/test/user2';

为了方便构造数据,本人将两个有数据的表建立成外部表,将最后的结果表建立成内部表。

create table user03(id int,username string) row format delimited fields terminated by '|';

user01表的数据内容:

1|user001
2|user002
3|user003
4|user004

user02表的数据内容:

1|user002
2|user006
3|user007
4|user009
5|user003

四、合并数据

在提取数据以前先来作个测试,以下的测试环境是Hive1.2.0版本:

select * from user01 union select * from user02;

结果以下图:

select username from user01 union select username user02;

结果以下图:

第三个语句和结果以下图:

从上述的实验,咱们能够看出:

  • 1.unoin去重的根据是把要展现的全部字段做为一个总体来去重的。
  • 2.unoin左右两边的字段结构要相同,此相同包括名称和个数,这个上面介绍已经说过了。
  • 3.unoin左右两边的字段结构不一样就会报错。

1.方法一

此方式采用的是CDH5.7中集成的Hive1.1.0版本实现。 这里能够一条HQL实现,HQL以下:

insert overwrite table user03 
select row_number() over() as id ,username from (
select distinct(username) as username from (
select username from user01 union all select username from user02) as A) as B;

这里须要说一下,去重的那一步,必须单独写,没办法加id,加上就报错,因此又在外面加了一层加ID的查询,而后再插入。

查询结果以下:

2.方法二

采用开源的Hive1.2.0版本进行,这里就比上面要简单多了,由于可使用去重了!

insert overwrite table user03 
select row_number() over() as id,username from (
select username from user01 union select username from user02) as A;

查询结果以下:

以上就是案例的整个过程!

上一篇:Hive应用:选取分隔符

下一篇:Hive应用:explode和lateral view

相关文章
相关标签/搜索