欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

由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)