Hive中各种join对比案例分析

SQL语句执行顺序

在这里插入图片描述
很多SQL的优化可以根据SQL语句的执行顺序来处理。

创建表和插入数据

将建表和插入数据语句写到一个join.sql SQL文件中

-- 使用db2数据库
use db2;
-- 如果存在,则删除表
drop table if exists stu;
drop table if exists score;

-- 创建stu表
create table if not exists stu(
id int,
name string
)
row format delimited fields terminated by '\t'
;

-- 创建score表
create table if not exists score(
id int,
name string,
score int
)
row format delimited fields terminated by '\t'
;

-- 向表中插入数据
insert into table stu values (1,'dh'),(2,'xd'),(3,'xe'),(4,'ch'),(5,'lj');
insert into table score values (1,'dh',100),(2,'xd','86'),(3,'xe',null),(4,'ch',94),(6,'xx',26);

将join.sql文件上传到服务器:

[root@mini001 join]# ll
total 4
-rw-r--r--. 1 root root 593 Sep  7 22:30 join.sql

执行hive语句:

[root@mini001 join]# hive -f join.sql

查看表中数据:

0: jdbc:hive2://mini001:10000> select * from stu;select * from score;
+---------+-----------+--+
| stu.id  | stu.name  |
+---------+-----------+--+
| 1       | dh        |
| 2       | xd        |
| 3       | xe        |
| 4       | ch        |
| 5       | lj        |
+---------+-----------+--+
5 rows selected (2.057 seconds)
+-----------+-------------+--------------+--+
| score.id  | score.name  | score.score  |
+-----------+-------------+--------------+--+
| 1         | dh          | 100          |
| 2         | xd          | 86           |
| 3         | xe          | NULL         |
| 4         | ch          | 94           |
| 6         | xx          | 26           |
+-----------+-------------+--------------+--+
5 rows selected (0.196 seconds)

内连接

内连接:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。

select
	st.id,
	st.name,
	sc.id,
	sc.name,
	sc.score
from stu st
inner join score sc on st.id=sc.id;

结果:

+--------+----------+--------+----------+-----------+--+
| st.id  | st.name  | sc.id  | sc.name  | sc.score  |
+--------+----------+--------+----------+-----------+--+
| 1      | dh       | 1      | dh       | 100       |
| 2      | xd       | 2      | xd       | 86        |
| 3      | xe       | 3      | xe       | NULL      |
| 4      | ch       | 4      | ch       | 94        |
+--------+----------+--------+----------+-----------+--+

默认情况下,join即为inner join,所以inner可以省略不写。

左外连接

左外连接:JOIN 操作符左边表中符合 WHERE 子句的所有记录将会被返回。

select
	st.id,
	st.name,
	sc.id,
	sc.name,
	sc.score
from stu st
left join score sc on st.id=sc.id
;

结果:

+--------+----------+--------+----------+-----------+--+
| st.id  | st.name  | sc.id  | sc.name  | sc.score  |
+--------+----------+--------+----------+-----------+--+
| 1      | dh       | 1      | dh       | 100       |
| 2      | xd       | 2      | xd       | 86        |
| 3      | xe       | 3      | xe       | NULL      |
| 4      | ch       | 4      | ch       | 94        |
| 5      | lj       | NULL   | NULL     | NULL      |
+--------+----------+--------+----------+-----------+--+
select 
	sc.id,
	sc.name,
	sc.score,
	st.id,
	st.name
from score sc
left join stu st on sc.id=st.id
;

结果:

+--------+----------+-----------+--------+----------+--+
| sc.id  | sc.name  | sc.score  | st.id  | st.name  |
+--------+----------+-----------+--------+----------+--+
| 1      | dh       | 100       | 1      | dh       |
| 2      | xd       | 86        | 2      | xd       |
| 3      | xe       | NULL      | 3      | xe       |
| 4      | ch       | 94        | 4      | ch       |
| 6      | xx       | 26        | NULL   | NULL     |
+--------+----------+-----------+--------+----------+--+

右外连接

右外连接:JOIN 操作符右边表中符合 WHERE 子句的所有记录将会被返回。

select
	st.id,
	st.name,
	sc.id,
	sc.name,
	sc.score
from stu st
right join score sc on st.id=sc.id
;

结果:

+--------+----------+--------+----------+-----------+--+
| st.id  | st.name  | sc.id  | sc.name  | sc.score  |
+--------+----------+--------+----------+-----------+--+
| 1      | dh       | 1      | dh       | 100       |
| 2      | xd       | 2      | xd       | 86        |
| 3      | xe       | 3      | xe       | NULL      |
| 4      | ch       | 4      | ch       | 94        |
| NULL   | NULL     | 6      | xx       | 26        |
+--------+----------+--------+----------+-----------+--+
select 
	sc.id,
	sc.name,
	sc.score,
	st.id,
	st.name
from score sc
right join stu st on sc.id=st.id
;

结果:

+--------+----------+-----------+--------+----------+--+
| sc.id  | sc.name  | sc.score  | st.id  | st.name  |
+--------+----------+-----------+--------+----------+--+
| 1      | dh       | 100       | 1      | dh       |
| 2      | xd       | 86        | 2      | xd       |
| 3      | xe       | NULL      | 3      | xe       |
| 4      | ch       | 94        | 4      | ch       |
| NULL   | NULL     | NULL      | 5      | lj       |
+--------+----------+-----------+--------+----------+--+

满外连接

满外连接:将会返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定字 段没有符合条件的值的话,那么就使用 NULL 值替代。

select
	st.id,
	st.name,
	sc.id,
	sc.name,
	sc.score
from stu st
full join score sc on st.id=sc.id
;

结果:

+--------+----------+--------+----------+-----------+--+
| st.id  | st.name  | sc.id  | sc.name  | sc.score  |
+--------+----------+--------+----------+-----------+--+
| 1      | dh       | 1      | dh       | 100       |
| 2      | xd       | 2      | xd       | 86        |
| 3      | xe       | 3      | xe       | NULL      |
| 4      | ch       | 4      | ch       | 94        |
| 5      | lj       | NULL   | NULL     | NULL      |
| NULL   | NULL     | 6      | xx       | 26        |
+--------+----------+--------+----------+-----------+--+

笛卡尔积

笛卡尔集会在下面条件下产生 :
(1)省略连接条件 ;
(2)连接条件无效 ;
(3)所有表中的所有行互相连接;

select
	st.id,
	st.name,
	sc.id,
	sc.name,
	sc.score
from stu st,score sc
;

结果:

+--------+----------+--------+----------+-----------+--+
| st.id  | st.name  | sc.id  | sc.name  | sc.score  |
+--------+----------+--------+----------+-----------+--+
| 1      | dh       | 1      | dh       | 100       |
| 2      | xd       | 1      | dh       | 100       |
| 3      | xe       | 1      | dh       | 100       |
| 4      | ch       | 1      | dh       | 100       |
| 5      | lj       | 1      | dh       | 100       |
| 1      | dh       | 2      | xd       | 86        |
| 2      | xd       | 2      | xd       | 86        |
| 3      | xe       | 2      | xd       | 86        |
| 4      | ch       | 2      | xd       | 86        |
| 5      | lj       | 2      | xd       | 86        |
| 1      | dh       | 3      | xe       | NULL      |
| 2      | xd       | 3      | xe       | NULL      |
| 3      | xe       | 3      | xe       | NULL      |
| 4      | ch       | 3      | xe       | NULL      |
| 5      | lj       | 3      | xe       | NULL      |
| 1      | dh       | 4      | ch       | 94        |
| 2      | xd       | 4      | ch       | 94        |
| 3      | xe       | 4      | ch       | 94        |
| 4      | ch       | 4      | ch       | 94        |
| 5      | lj       | 4      | ch       | 94        |
| 1      | dh       | 6      | xx       | 26        |
| 2      | xd       | 6      | xx       | 26        |
| 3      | xe       | 6      | xx       | 26        |
| 4      | ch       | 6      | xx       | 26        |
| 5      | lj       | 6      | xx       | 26        |
+--------+----------+--------+----------+-----------+--+
select 
	sc.*,
	st.*
from score sc,stu st
;

结果:

+--------+----------+-----------+--------+----------+--+
| sc.id  | sc.name  | sc.score  | st.id  | st.name  |
+--------+----------+-----------+--------+----------+--+
| 1      | dh       | 100       | 1      | dh       |
| 1      | dh       | 100       | 2      | xd       |
| 1      | dh       | 100       | 3      | xe       |
| 1      | dh       | 100       | 4      | ch       |
| 1      | dh       | 100       | 5      | lj       |
| 2      | xd       | 86        | 1      | dh       |
| 2      | xd       | 86        | 2      | xd       |
| 2      | xd       | 86        | 3      | xe       |
| 2      | xd       | 86        | 4      | ch       |
| 2      | xd       | 86        | 5      | lj       |
| 3      | xe       | NULL      | 1      | dh       |
| 3      | xe       | NULL      | 2      | xd       |
| 3      | xe       | NULL      | 3      | xe       |
| 3      | xe       | NULL      | 4      | ch       |
| 3      | xe       | NULL      | 5      | lj       |
| 4      | ch       | 94        | 1      | dh       |
| 4      | ch       | 94        | 2      | xd       |
| 4      | ch       | 94        | 3      | xe       |
| 4      | ch       | 94        | 4      | ch       |
| 4      | ch       | 94        | 5      | lj       |
| 6      | xx       | 26        | 1      | dh       |
| 6      | xx       | 26        | 2      | xd       |
| 6      | xx       | 26        | 3      | xe       |
| 6      | xx       | 26        | 4      | ch       |
| 6      | xx       | 26        | 5      | lj       |
+--------+----------+-----------+--------+----------+--+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值