關鍵字: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)
只返回能關聯上的結果。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
以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
和左外關聯相反,以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
以兩個表的記錄爲基準,返回兩個表的記錄去重之和,關聯不上的字段爲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
以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
返回兩個表的笛卡爾積結果,不須要指定關聯鍵。
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中只要是涉及到兩個表關聯,首先得了解一下數據,看是否存在多對多的關聯。