由LEFT SEMI JOIN所聯想到的

一、LEFT SEMI JOIN 與 INNER JOIN的區別

1. LEFT SEMI JOIN 

LEFT SEMI JOIN 是 IN/EXISTS 子查詢的一種更高效的實現。
Hive 當前沒有實現 IN/EXISTS 子查詢,所以你可以用 LEFT SEMI JOIN 重寫子查詢語句。LEFT SEMI JOIN 的限制是, JOIN 子句中右邊的表只能在 ON 子句中設置過濾條件,在 WHERE 子句、SELECT 子句或其他地方過濾都不行。

 SELECT a.key, a.value
  FROM a
  WHERE a.key in
   (SELECT b.key
    FROM B);
可以被重寫爲:
   SELECT a.key, a.val
   FROM a LEFT SEMI JOIN b on (a.key = b.key)

2.INNER JOIN

INNER JOIN 等價於 JOIN,可以理解爲 JOIN是 INNER JOIN 的縮寫。

3.區別

HIVE中都是等值連接,在JOIN使用的時候,有兩種寫法在理論上是可以達到相同的效果的,但是由於實際情況的不一樣,子表中數據的差異導致結果也不太一樣。
當子表(tab2)中存在重複的數據,當使用JOIN ON的時候,A,B表會關聯出兩條記錄,應爲ON上的條件符合;而是用LEFT SEMI JOIN 當A表中的記錄,在B表上產生符合條件之後就返回,不會再繼續查找B表記錄了,所以如果B表有重複,也不會產生重複的多條記錄。

二、數據樣例測試

1、造測試數據

drop table if exists tmp.tab1;
create table tmp.tab1 as
select 1 id,'a' name,90 score
union all
select 2 id,'b' name,80 score
union all
select 3 id,'c' name,85 score;

drop table if exists tmp.tab2;
create table tmp.tab2 as
select 2 id,'b' name,80 score
union all
select 3 id,'c' name,85 score
union all
select 4 id,'d' name,90 score;

2、查詢測試

2.1、LEFT JOIN=LEFT OUTER JOIN

SELECT a1.id,
       a1.name,
       a1.score
FROM tmp.tab1 a1
LEFT JOIN tmp.tab2 a2 ON a1.id=a2.id;

OK
1       a       90
2       b       80
3       c       85
Time taken: 19.636 seconds, Fetched: 3 row(s)
SELECT a1.id,
       a1.name,
       a1.score
FROM tmp.tab1 a1
LEFT OUTER JOIN tmp.tab2 a2 ON a1.id=a2.id;

OK
1       a       90
2       b       80
3       c       85
Time taken: 17.025 seconds, Fetched: 3 row(s)

2.2、LEFT SEMI JOIN ~= INNER JOIN

SELECT a1.id,
       a1.name,
       a1.score
FROM tmp.tab1 a1 LEFT SEMI
JOIN tmp.tab2 a2 ON a1.id=a2.id;

OK
2       b       80
3       c       85
Time taken: 20.815 seconds, Fetched: 2 row(s)
SELECT a1.id,
       a1.name,
       a1.score
FROM tmp.tab1 a1
INNER
JOIN tmp.tab2 a2 ON a1.id=a2.id;

OK
2       b       80
3       c       85
Time taken: 20.791 seconds, Fetched: 2 row(s)

2.3、全連接

SELECT a1.id,
       a1.name,
       a1.score
FROM tmp.tab1 a1
FULL
JOIN tmp.tab2 a2 ON a1.id=a2.id;

OK
1       a       90
2       b       80
3       c       85
NULL    NULL    NULL
Time taken: 20.102 seconds, Fetched: 4 row(s)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章