1内连接
2外链接
3半连接
4笛卡尔连接
5其他连接方式(eg.mapjoin等)
hive只支持等值连接
多表连接的时候,一般先进行left semi join(半连接),然后再进行join,再进行外链接(减少数据量)
也就是说如果表比较稀疏,是很能减少数据量的。
执行以下语句,左半连接用来代替in操作或者exists操作的
select * from user left semi join job on user.id=job.user_id;
结果如下
该语句相当于如下语句
select * from user where id in (select user_id from job);
但是,Hive不支持in子句。所以只能变通,使用left semi子句。
一般是先进行join后进行where,join的过滤条件可以将where的过滤条件移动到join的过滤条件中去。这样可以减少网络数据量。
join执行顺序都是从左到右的,不管是那种join方式,那么一般将大的表放在右边,这样可以节省内存&减少网络传输。
mapjoin是只适合连接表是小表的情况,是一种空间换时间的解决方案,这个只有在数据量特别大的情况下才能体现出来。
内连接主要作用是获取连接的两张表全部匹配的数据,如果不给定join_condition的话,会进行笛卡尔乘积。笛卡尔连接(cross join)和内连接语法一样。
区别在于笛卡尔连接是内连接的一种优化。
//内连接,获取学生和班级之间完全匹配的数据。
select students.*, classes.* from classes join students on classes.id= students.classid and classes.classid = 1;
//笛卡尔连接
select student.*, classes.* from classes cross join students on classes.classid = students.classid;
外链接的主要作用是保留一部分没有匹配的数据。左外连接的结果是包含左表中的所有行,如果左表中的某一行在右表中不存在,那么则在相关关联的结果集中右表的所有选择列值均设置为空值。右外链接同理。
全外连接返回左表和右表的所有行,关联表中没有匹配值的直接设置为空值。
// 获取全部学生的班级信息,如果该学生没有分配班级,那么班级信息显示为null
select students.* , class.* from students left join classes on students.classid = classes.classid;
//获取学生表中班级id在班级表中的所有学生信息。
sql: select student.* from students where classid in (select distinct classid from classes);
原hql:select student.* from students join classes on students.classid = classes.classid;
新hql:select students.* from students left semi join classes on students.classid = classes.classid;
mapjoin:
select /*+ mapjoin(classes) */ * from students join classes on students.classid = classes.classid;