Hive中Join的類型和用法

關鍵字:Hive Join、Hive LEFT|RIGTH|FULL OUTER JOIN、Hive LEFT SEMI JOIN、Hive Cross Join數據庫

Hive中除了支持和傳統數據庫中同樣的內關聯、左關聯、右關聯、全關聯,還支持LEFT SEMI JOIN和CROSS JOIN,但這兩種JOIN類型也能夠用前面的代替。優化

注意:Hive中Join的關聯鍵必須在ON ()中指定,不能在Where中指定,不然就會先作笛卡爾積,再過濾。spa

數據準備:code

 1     hive> desc lxw1234_a;
 2     OK
 3     id string
 4     name string
 5     Time taken: 0.094 seconds, Fetched: 2 row(s)
 6     hive> select * from lxw1234_a;
 7     OK
 8     1 zhangsan
 9     2 lisi
10     3 wangwu
11     Time taken: 0.116 seconds, Fetched: 3 row(s)
12     hive> desc lxw1234_b;
13     OK
14     id string
15     age int
16     Time taken: 0.159 seconds, Fetched: 2 row(s)
17     hive> select * from lxw1234_b;
18     OK
19     1 30
20     2 29
21     4 21
22     Time taken: 0.09 seconds, Fetched: 3 row(s)

 

 

10.1 內關聯(JOIN)

只返回能關聯上的結果。blog

 1     SELECT a.id,
 2     a.name,
 3     b.age
 4     FROM lxw1234_a a
 5     join lxw1234_b b
 6     ON (a.id = b.id);
 7      
 8     --執行結果
 9      
10     1 zhangsan 30
11     2 lisi 29

 

10.2 左外關聯(LEFT [OUTER] JOIN)

以LEFT [OUTER] JOIN關鍵字前面的表做爲主表,和其餘表進行關聯,返回記錄和主表的記錄數一致,關聯不上的字段置爲NULL。string

是否指定OUTER關鍵字,貌似對查詢結果無影響。class

 1     SELECT a.id,
 2     a.name,
 3     b.age
 4     FROM lxw1234_a a
 5     left join lxw1234_b b
 6     ON (a.id = b.id);
 7      
 8     --執行結果:
 9     1 zhangsan 30
10     2 lisi 29
11     3 wangwu NULL

 

10.3 右外關聯(RIGHT [OUTER] JOIN)

和左外關聯相反,以RIGTH [OUTER] JOIN關鍵詞後面的表做爲主表,和前面的表作關聯,返回記錄數和主表一致,關聯不上的字段爲NULL。select

是否指定OUTER關鍵字,貌似對查詢結果無影響。im

 1     SELECT a.id,
 2     a.name,
 3     b.age
 4     FROM lxw1234_a a
 5     RIGHT OUTER JOIN lxw1234_b b
 6     ON (a.id = b.id);
 7      
 8     --執行結果:
 9     1 zhangsan 30
10     2 lisi 29
11     NULL NULL 21

10.4 全外關聯(FULL [OUTER] JOIN)

以兩個表的記錄爲基準,返回兩個表的記錄去重之和,關聯不上的字段爲NULL。經驗

是否指定OUTER關鍵字,貌似對查詢結果無影響。

注意:FULL JOIN時候,Hive不會使用MapJoin來優化。

 1 SELECT a.id,
 2 a.name,
 3 b.age
 4 FROM lxw1234_a a
 5 FULL OUTER JOIN lxw1234_b b
 6 ON (a.id = b.id);
 7  
 8 --執行結果:
 9 1 zhangsan 30
10 2 lisi 29
11 3 wangwu NULL
12 NULL NULL 21

 

10.5 LEFT SEMI JOIN

以LEFT SEMI JOIN關鍵字前面的表爲主表,返回主表的KEY也在副表中的記錄。

 1     SELECT a.id,
 2     a.name
 3     FROM lxw1234_a a
 4     LEFT SEMI JOIN lxw1234_b b
 5     ON (a.id = b.id);
 6      
 7     --執行結果:
 8     1 zhangsan
 9     2 lisi
10      
11     --等價於:
12     SELECT a.id,
13     a.name
14     FROM lxw1234_a a
15     WHERE a.id IN (SELECT id FROM lxw1234_b);
16      
17      
18     --也等價於:
19     SELECT a.id,
20     a.name
21     FROM lxw1234_a a
22     join lxw1234_b b
23     ON (a.id = b.id);
24      
25     --也等價於:
26     SELECT a.id,
27     a.name
28     FROM lxw1234_a a
29     WHERE EXISTS (SELECT 1 FROM lxw1234_b b WHERE a.id = b.id);
30      

 

10.6 笛卡爾積關聯(CROSS JOIN)

返回兩個表的笛卡爾積結果,不須要指定關聯鍵。

 1     SELECT a.id,
 2     a.name,
 3     b.age
 4     FROM lxw1234_a a
 5     CROSS JOIN lxw1234_b b;
 6      
 7     --執行結果:
 8     1 zhangsan 30
 9     1 zhangsan 29
10     1 zhangsan 21
11     2 lisi 30
12     2 lisi 29
13     2 lisi 21
14     3 wangwu 30
15     3 wangwu 29
16     3 wangwu 21
17      

Hive中的JOIN類型基本就是上面這些,至於JOIN時候使用哪種,徹底得根據實際的業務需求來定,但起碼你要搞清楚這幾種關聯類型會返回什麼樣的結果。

除非特殊需求,而且數據量不是特別大的狀況下,才能夠慎用CROSS JOIN,不然,很難跑出正確的結果,或者JOB壓根不能執行完。

經驗告訴我,Hive中只要是涉及到兩個表關聯,首先得了解一下數據,看是否存在多對多的關聯。

相關文章
相關標籤/搜索