hive表連線的語法支援如下:
join_table:
table_reference join table_factor [join_condition]
| table_reference [outer] join table_reference join_condition
| table_reference left semi join table_reference join_condition
| table_reference cross
join table_reference [join_condition] (as
of hive 0.10)
table_reference:
table_factor
| join_table
table_factor:
tbl_name [alias]
| table_subquery alias
| ( table_references )
join_condition:
on equality_expression ( and equality_expression )*
equality_expression:
expression = expression
hive只支援等連線,外連線,左半連線。hive不支援非相等的join條件(可以通過其他方式實現),因為它很難在map/reduce job實現這樣的條件。而且,hive可以join兩個以上的表。
例子寫join查詢時,有幾個典型的點要考慮,如下:
等鏈結
只有等鏈結是允許的:
select a.* from a join b on (a.id = b.id and a.department = b.department)
這個非等值鏈結是不合法的:
select a.* from a join b on (a.id < b.id)
但是可以用如下方式實現:
select a.* from a join b on (true) where
a.id < b.id
多表連線
同個查詢,可以join兩個以上的表:
select a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key2)
需要注意的是,多個表join時,最好按照表由小到大的順序join。雖然實際原因要考慮資料傾斜等問題,此處不展開敘述。
join的快取和任務轉換
hive轉換多表join時,如果每個表在join字句中,使用的都是同乙個列,只會轉換為乙個單獨的map/reduce。
例如:這個會轉換為單獨的map/reduce任務,只有b表的key1列在join被呼叫。
select a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key1)
select a.val, b.val, c.val from a join b on (a.key = b.key1) join c on (c.key = b.key2)
被轉換為兩個map/reduce任務,因為b的key1列在第乙個join條件使用,而b表的key2列在第二個join條件使用。第乙個map/reduce任務join a和b。第二個任務是第乙個任務的結果join c
join的結果
left,right,full outer連線存在是為了提供on語句在沒有匹配時的更多控制。例如,這個查詢:
select a.val, b.val from a left outer join b on (a.key=b.key)
由於鏈結的字段是key,不存在一對多,所以將會返回a的每一行。如果b.key等於a.key,輸出將是a.val,b.val,如果a沒有和b.key匹配,輸出的行將是 a.val,null。如果b的行沒有和a.key匹配上,將被拋棄。語法"from a left outer join b"必須寫在一行,為了理解它如何工作——這個查詢,a是b的左邊,a的所有行會被保持;right outer join將保持b的所有行, full outer join將會儲存a和b的所有行。outer join語義應該符合標準的sql規範。
join的過濾
joins發生在where字句前,所以,如果要限制join的輸出,需要寫在where字句,否則寫在join字句。現在討論的乙個混亂的大點,就是分割槽表
sql**
select a.val, b.val from a left
outer
join b on (a.key=b.key)
where a.ds='2000-01-01'
and b.ds='2000-01-01'
將會連線a和b,產生a.val和b.val的列表。where字句,也可以引用join的輸出列,然後過濾他們。
但是,無論何時join的行找到a的key,但是找不到b的key時,b的所有列會置成null,包括ds列。這就是說,將過濾join輸出的所有行,包括沒有合法的b.key的行。然後你會在left outer的要求撲空。
也就是說,如果你在where字句引用b的任何列,left outer的部分join結果是不相關的。所以,當外連線時,使用這個語句
sql**
select a.val, b.val from a left
outer
join b on (a.key=b.key
and b.ds='2000-01-01'
and a.ds='2000-01-01'
join的輸出會預先過濾,然後你不用對有a.key而沒有b.key的行做過濾。right和full join也是一樣的邏輯
HIVE的6種join用法
給自己留檔,基本是從這個部落格抄來的。例子 兩個 表a id name1張三 2李四3王五 表b id age1202 29430join 內關聯,只返回兩個表中關聯上的結果 select a.id,a.name,b.age from a join b on a.id b.id得到結果 a.id a...
Hive中的Join操作
hive中有許多的join操作,如果left,right和full outer join,inner join,left semi join等。那麼它們都各自有什麼特點呢?感覺很難說明這些區別,還是通過例子來看。如果我們有乙個表,資料如下 a.txt 1,a 2,b3,c 4,d7,y 8,u另乙個...
HIVE中的join語句
hive支援通常的sql join語句,但是只支援等值連線。1.1 inner join 只有進行連線的兩個表都存在與連線標準相匹配的資料才會儲存下來 select a.ymd a.price b.price from stocks a join stocks b on a.ymd b.ymd wh...