本文參考官方介紹,原文地址以下: 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應用:選取分隔符