由LEFT SEMI JOIN所联想到的
程序员文章站
2022-07-14 16:16:55
...
一、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)