2021-09-13

hive中的join

hive有很多join,这些join之间是有差别的,总结这些join可以让我们在不同场景下更充分更灵活的去使用,从而使我们在日常工作中更加效率。



hive中有哪些join?

以下几种:hive中大致包含6种join,分别是inner join、left join、full join、right join、left semi join、cross join这6种。其中left join、right join、full join也叫做left outer join、right outer join、full outer join。

一、hive中的各个join

1.left join

如果说join中哪个最重要,哪个用的最多,那必定是left join。left join是left outer join的缩写,两者功能完全一样,也就是我们通常所说的左连接,这个是目前生产上用的最为广泛的join之一。下面我们来详细介绍一下左连接,左连接顾名思义以左表为主表去关联其他表,通过关联条件关联上的就可以从从表中取从表中的值,如果关联不上那么从表中取的值就会是NULL,也就是我们通常说的空。
下面我们举例说明(示例):
假设有两张表分别为 tableA 和 tableB ,两张表的分别有id和name,两者结合构成联合主键
首先准备测试数据

创建表A tableA
create table tableA(
id int
,name varchar(20)
);
想表A中插入数据
insert into tableA values
(1,‘张三’)
,(2,‘李四’)
,(3,‘王五’)
,(4,‘小航’)
,(5,‘小刘’)
,(6,‘小张’);
–创建表B tableB
create table tableB(
id int
,name varchar(20)
);
–向表B中插入数据
insert into tableB values
,(1,‘小张’)
,(2,‘李四’)
,(3,‘王五’)
,(4,‘航航’)
,(5,‘刘小’)
,(6,‘小兵张’);

select * from tableA a 
left join tableB b
on a.id = b.id
and a.name = b.name 

A表和B表通过id和name关联,只有A和B中id和name同时相等时才能同时取到两者都不为NULL的情况,如A表中的id为2,name为’李四’的的这条数据,在B表中存在一条一模一样的数据,所以如下结果中会发现id为2,name为‘李四’的这条数据A表和 B表都取到了。A表中id为1,name为’张三’的这条数据去和B表中的数据关联,A表中的id和B表中的id相同但是name不一样,两者必须同时相等才算关联上,A表为主表作为主表,B表作为从表,所以出现取到A表中数据为本来数据,取到B表中的数据为NULL这种情况。

a.ida.nameb.idb.name
1张三NULLNULL
2李四2李四
3王五3王五
4小航NULLNULL
5小刘NULLNULL
6小张NULLNULL

2.right join

右连接其实和左连接是一样的,就像数学中加减法一样,其实加减法可以归为一类,加法可以转化为减法,就比如说 1+1=2,我们转化为减法就可以写成1-(-1)=2。
同理。right join
a right join b 就可以写成 b left join a,只需考虑换一下两张表的位置即可。多数人更倾向于直接将right join改写成left join。

3.full join

full join其实等价于full outer join,full join其实相当于left join 和right join的结合。
我们还以A表和B表为例子,看一下结果

select * from tableA a 
full join tableB b
on a.id = b.id
and a.name = b.name 

结果如下:

a.ida.nameb.idb.name
NULLNULL1小张
1张三NULLNULL
2李四2李四
3王五3王五
4小航NULLNULL
NULLNULL4航航
NULLNULL5刘小
5小刘NULLNULL
NULLNULL6小兵张
6小张NULLNULL

4.inner join

inner join 其实和 join是一样的,有时我们会省略到中间的inner。inner join会通常用来求交集,就比如说:求tableA和tableB的交集。

select * from tableA a 
inner join tableB b
on a.id = b.id
and a.name = b.name 

inner join的结果如下:

a.ida.nameb.idb.name
2李四2李四
3王五3王五

我们再来试一下直接join

select * from tableA a 
join tableB b
on a.id = b.id
and a.name = b.name 

直接join的结果如下:

a.ida.nameb.idb.name
2李四2李四
3王五3王五

扩展:通过where连接的隐形连接也能起到同样的效果。

select * from tableA a ,tableB b
where a.id = b.id
and a.name = b.name 

5.cross join

笛卡尔积连接,假设左表有n行,右表有m行,那么最终的输出结果有n*m行结果。

select * from tableA a 
cross join tableB b

cross join的数据结果如下(36行即6*6):

a.ida.nameb.idb.name
1张三1小张
2李四1小张
3王五1小张
4小航1小张
5小刘1小张
6小张1小张
1张三2李四
2李四2李四
3王五2李四
4小航2李四
5小刘2李四
6小张2李四
1张三3王五
2李四3王五
3王五3王五
4小航3王五
5小刘3王五
6小张3王五
1张三4航航
2李四4航航
3王五4航航
4小航4航航
5小刘4航航
6小张4航航
1张三5刘小
2李四5刘小
3王五5刘小
4小航5刘小
5小刘5刘小
6小张5刘小
1张三6小兵张
2李四6小兵张
3王五6小兵张
4小航6小兵张
5小刘6小兵张
6小张6小兵张

6.left semi join

LEFT SEMI JOIN 左半连接 相当于 in/exist的优化.
在这里插入图片描述
在这里插入图片描述
注:以上图片转载自:https://blog.csdn.net/HappyRocking/article/details/79885071

1、left semi join 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。

2、left semi join 是只传递表的 join key 给 map 阶段,因此left semi join 中最后 select 的结果只许出现左表。

3、因为 left semi join 是 in(keySet) 的关系,遇到右表重复记录,左表会跳过,而 join 则会一直遍历。这就导致右表有重复值得情况下 left semi join 只产生一条,join 会产生多条,也会导致 left semi join 的性能更高。
在这里插入图片描述

原文链接:https://blog.csdn.net/HappyRocking/article/details/79885071

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值