好程序员大数据学习路线之hive表的查询   1.join 查询   1、永远是小结果集驱动大结果集(小表驱动大表,小表放在左表)。 2、尽量不要使用join,但是join是难以避免的。   left join 、 left outer join 、 left semi join(左半开连接,只显示左表信息)   hive在0.8版本以后开始支持left join   left join 和 left outer join 效果差不多   hive的join中的on只能跟等值连接 "=",不能跟< >= <= !=   join:不加where过滤,叫笛卡尔积   inner join : 内连接   outer join :外链接   full outer join : 全外连接,寻找表中所有满足连接(包括where过滤)。   ##创建学生测试表 CREATE TABLE student ( id INT, name string, sex string, birth string, department string, address string ) row format delimited fields terminated by ',' ; ##从本地加载数据 load data local inpath '/root/Desktop/student.txt' into table student; ##创建学生成绩测试表 CREATE TABLE score ( stu_id INT, c_name string, grade string ) row format delimited fields terminated by ',' ; ##从hdfs加载数据 load data inpath '/hive.data/score.txt' into table score; ##创建学生基本信息测试表 create table stuinfo( id int, height double, weight double ) row format delimited fields terminated by ',' ; ##从本地加载数据 load data local inpath '/root/Desktop/stuinfo.txt' into table stuinfo;   1.1 左连接   如果左边有数据,右边没有数据,则左边有数据的记录的对应列返回为空。   ##使用左连接查询:student表为驱动表,通过id连接 select student.name, score.c_name, score.grade from student left join score on student.id = score.stu_id ;   1.2 左外连接   如果左边有数据,右边没有数据,则左边有数据的记录的对应列返回为空。   ##使用左外连接查询:student表为驱动表,通过id连接 select student.name, score.c_name, score.grade from student left outer join score on student.id = score.stu_id ;   1.3 左半连接   left semi join是left join 的一种优化,并且通常用于解决exists in,写left semi join 查询时必须遵循一个限制:右表(sales) 只能在 on子句中出现,且不能在select 表达式中引用右表。   ##左半连接 select student.* from student left semi join score on student.id=score.id ; ##查询结果等价于 select * from student where student.id not in (select stu_id from score);   1.4 右外连接   right outer join和right join差不多,不常用   如果左边没有数据,右边有数据,则右边有数据的记录对应列返回为空。   ##使用右外连接查询:score表为驱动表,通过id连接 select student.name, score.c_name, score.grade from student right outer join score on student.id = score.stu_id ;   1.5 全外连接   ##全外连接 select student.name, score.c_name, score.grade from student full outer join score on student.id = score.stu_id ;   ##不使用join,from 后面跟多个表名使用","分割 、 inner join 、join :三种效果一样 select student.name, score.c_name, score.grade from student,score where student.id = score.stu_id ;   1.6 内连接   ##使用内连接查询所有有考试成绩的学生的学生姓名,学科名,学科成绩,及身高 select student.name, score.c_name, score.grade, stuinfo.height from student inner join score on student.id = score.stu_id join stuinfo on student.id = stuinfo.id ;   1.7 hive提供一个小表标识,是hive提供的一种优化机制   ##小表标识:/+STREAMTABLE(表名)/ select /+STREAMTABLE(score)/ student.name, score.c_name, score.grade, stuinfo.height from student inner join score on student.id = score.stu_id join stuinfo on student.id = stuinfo.id ;   1.8 map-side join:   如果有一个连接表小到足以放入内存, Hive就可以把较小的表放入每个mapper的内存来执行连接操作。这就叫做map连接。当有一大一小表的时候,适合用map-join。会将小表文件缓存,放到内存中,在map端和内存中的数据一一进行匹配,连接查找关系。hive-1.2.1 默认已经开启map-side join:hive.auto.convert.join=true   select student.name, score.c_name, score.grade, stuinfo.height from student inner join score on student.id = score.stu_id join stuinfo on student.id = stuinfo.id ;   hive 0.7版本以前,需要hive提供的mapjoin()标识。来标识该join为map-side join。标识已经过时,但是写上仍然识别   select /+MAPJOIN(student)/ student.name, score.c_name, score.grade, stuinfo.height from student inner join score on student.id = score.stu_id join stuinfo on student.id = stuinfo.id ;   hive怎么知道将多大文件缓存,配置文件中配置,下面为默认配置   <property> <name>hive.mapjoin.smalltable.filesize</name> <value>25000000</value> </property>   2.group by:   GROUP BY 语句通常会和聚合函数一起使用,按照一个或者多个列对结果进行分组,然后对每个组执行聚合操作。使用group by后,查询的字段要么出现在聚合函数中,要么出现在group by 后面。   ##查询学生的考试门数,及平均成绩 select count(), avg(grade) from student join score on student.id=score.stu_id group by student.id;   3.where   SELECT语句用于选取字段,WHERE语句用于过滤条件,两者结合使用可以查找到符合过滤条件的记录。后面不能跟聚合函数或者聚合函数的结果,能跟普通的查询值或者是方法   ##查询学生的考试平均成绩大于90分 select count(), avg(grade) avg_score from student join score on student.id=score.stu_id where student.id<106 group by student.id having avg_score>90;   4.having:   对查询出来的结果进行过滤,通常和group by搭配使用。   ##查询学生的考试平均成绩大于90分的学生id及平均成绩 select count(*), avg(grade) avg_score from student join score on student.id=score.stu_id group by student.id having avg_score>90;   5.排序   sort by :排序,局部排序,只能保证单个reducer的结果排序。 order by: 排序,全局排序。保证整个job的结果排序。 当reducer只有1个的时候,sort by 和 order by 效果一样。建议使用sort by 通常和: desc asc .(默认升序)   ##查询学生平均成绩按照降序排序 select avg(grade) avg_score from student join score on student.id=score.stu_id group by student.id order by avg_score desc;   设置reducer个数(等于1 或者 2):   set mapreduce.job.reduces=2   ##使用order by select avg(grade) avg_score from student join score on student.id=score.stu_id group by student.id order by avg_score desc; ##使用sort by select avg(grade) avg_score from student join score on student.id=score.stu_id group by student.id sort by avg_score desc;   6.distribute by:   控制map中如何输出到reduce。整个hive语句转换成job默认都有该过程,如果不写,默认使用第一列的hash值来分。当只有一个reducer的时候不能体现出来。如果distribute by和sort by 一起出现的时候注意顺序问题??distribute by在前面   clusterd by : 它等价于distribute by和sort by(升序)。后面跟的字段名需要一样 clusterd by它既兼有distribute by,还兼有sort by (只能是升序)   select id from student distribute by id sort by id;   select id from student clusterd by id;   7.limit : 限制结果集的。   select id,name from student limit 3;   8.union all:   将两个或者多个查询的结果集合并到一起,不去重每一个结果集排序。字段数必须一致,字段类型尽量相同   ##将id<108的和id>103的使用union all合并 select id sid, name snames from student where id<108 union all select id sid, name sname from student where id>103;   9.union:   将两个或者多个查询结果集合并到一起,去重,合并后的数据排序   ##将id<108的和id>103的使用union合并 select id sid, name sname from student where id<108 union select id sid, name sname from student where id>103 order by sname;   10.子查询   子查询是内嵌在另一个SQL 语句中的SELECT 语句。Hive 对子查询的支持很有限。它只允许子查询出现在SELECT 语句的FROM 子句中。Hive支持非相关子查询,这个子查询通过IN或EXISTS语法在WHERE子句中进行查询。Hive目前暂不支持相关子查询,相关子查询的执行依赖于外部查询的数据。   ##非相关子查询 select id,name from student where id in (select stu_id from score);   ##相关子查询的执行依赖于外部查询的数据 select sid,uname from (select id sid, name uname from student ) s order by sid ##外层查询像访问表那样访问子查询的结果,这是为什么必须为子查询赋予一个别名(s)的原因。子查询中的列必须有唯一的名称,以便外层查询可以引用这些列。