本文参考官方介绍,原文地址以下: 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 |
官方语法:code
select_statement UNION [ALL | DISTINCT] select_statement UNION [ALL | DISTINCT] select_statement ...
union用于将多个select语句的结果组合到单个结果集中。orm
须要注意:blog
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)
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
本人本身寻找了一个使用此语法的案例,这里和你们进行分享。若有错误敬请指正。
存在两张用户表,一张为历史表,一张为当日表,天天要将当日表中的数据和历史表中的数据进行去重合并到新的历史表中。
这里本人首先想到的步骤是,将两张表的数据进行合并,而后查询全部去重存入另一张表。 这个思路的实现局限于hive的版本,这里提供两个版本的,两种方式进行实现,更高的2.2.0版本,本人没有使用,这里使用的两个版本分别是CDH中集成的hive1.1.0版本和开源的hive1.2.0版本。
建立三张表:
建表语句:
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;
结果以下图:
第三个语句和结果以下图:
从上述的实验,咱们能够看出:
此方式采用的是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的查询,而后再插入。
查询结果以下:
采用开源的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应用:选取分隔符