简单练习---学生课程信息

###1.1、表结构及样例数据

create table student(Sno int,Sname string,Sex string,Sage int,Sdept string)
row format delimited fields terminated by ','stored as textfile;
95001,李勇,男,20,CS
95002,刘晨,女,19,IS
95003,王敏,女,22,MA
95004,张立,男,19,IS
95005,刘刚,男,18,MA
95006,孙庆,男,23,CS
95007,易思玲,女,19,MA
95008,李娜,女,18,CS
95009,梦圆圆,女,18,MA
95010,孔小涛,男,19,CS
95011,包小柏,男,18,MA
95012,孙花,女,20,CS
95013,冯伟,男,21,CS
95014,王小丽,女,19,CS
95015,王君,男,18,MA
95016,钱国,男,21,MA
95017,王风娟,女,18,IS
95018,王一,女,19,IS
95019,邢小丽,女,19,IS
95020,赵钱,男,21,IS
95021,周二,男,17,MA
95022,郑明,男,20,MA

create table course(Cno int,Cname string)
row format delimited fields terminated by ',' stored as textfile;
1,数据库
2,数学
3,信息系统
4,操作系统
5,数据结构
6,数据处理


create table sc(Sno int,Cno int,Grade int)
row format delimited fields terminated by ',' stored as textfile;
95001,1,81
95001,2,85
95001,3,88
95001,4,70
95002,2,90
95002,3,80
95002,4,71
95002,5,60
95003,1,82
95003,3,90
95003,5,100
95004,1,80
95004,2,92
95004,4,91
95004,5,70
95005,1,70
95005,2,92
95005,3,99
95005,6,87
95006,1,72
95006,2,62
95006,3,100
95006,4,59
95006,5,60
95006,6,98
95007,3,68
95007,4,91
95007,5,94
95007,6,78
95008,1,98
95008,3,89
95008,6,91
95009,2,81
95009,4,89
95009,6,100
95010,2,98
95010,5,90
95010,6,80
95011,1,81
95011,2,91
95011,3,81
95011,4,86
95012,1,81
95012,3,78
95012,4,85
95012,6,98
95013,1,98
95013,2,58
95013,4,88
95013,5,93
95014,1,91
95014,2,100
95014,4,98
95015,1,91
95015,3,59
95015,4,100
95015,6,95
95016,1,92
95016,2,99
95016,4,82
95017,4,82
95017,5,100
95017,6,58
95018,1,95
95018,2,100
95018,3,67
95018,4,78
95019,1,77
95019,2,90
95019,3,91
95019,4,67
95019,5,87
95020,1,66
95020,2,99
95020,5,93
95021,2,93
95021,5,91
95021,6,99
95022,3,69
95022,4,93
95022,5,82
95022,6,100

1.2、加载数据

load data local inpath '/uardata/hivetest/students.txt' overwrite into table student;
load data local inpath '/uardata/hivetest/sc.txt' overwrite into table sc;
load data local inpath '/uardata/hivetest/course.txt' overwrite into table course;

1.3、简单查询

查询全体学生的学号与姓名
    select Sno, Sname from student;
查询选修了课程的学生姓名
    select Sname from student s where s.Sdept is not null;

1.4、hive的group by 和集合函数

查询学生的总人数
    select count(*) from student;
计算1号课程的学生平均成绩
    select avg(s.Grade) from sc s where s.Grade = 1;
查询各科成绩平均分
    select sc.cno, avg(sc.grade) from sc group by sc.cno;
查询选修1号课程的学生最高分数
  select max(sc.grade) from sc where sc.cno=1;
求各个课程号及相应的选课人数 
    select sc.cno, count(*)  from sc group by sc.cno;
查询选修了3门以上的课程的学生学号
    -- 注意group by 不能与where在一起
    select count(*) scount, sno from sc group by sno having scount > 3;

1.5、Order By/Sort By/Distribute By

参考https://blog.csdn.net/zhousishuo/article/details/79166874

1.order by 子句
在order by子句中有一些限制。在strict模式(hive.mapred.mode=strict)下,order by子句后面必须有limit子句。如果设置hive.mapred.mode=nonstrictlimit子句不一定需要。原因是为了对所有结果进行整体的排序,必须使用一个reducer来对最后的结果进行排序。如果结果的总行数太大,单个reducer可能需要很长的时间完成。

order by默认顺序是升序(asc)。在Hive 2.1.0及以上版本,支持对null值进行排序,升序排序是null值被排在第一位,降序时null值被排在最后。

2.sort by 和 order by 之间的区别
Hive支持使用 sort by 排序。
sort byorder by的区别是前者给每一reducer上的所有行进行排序,后者保证在数据结果上都有序。也就是说,如果使用超过一个reducer,使用sort by可能给出部分有序的结果。

3.使用sort by会在每个reducer中的数据将会根据用户指定的顺序排序

SELECT key, value FROM src SORT BY key ASC, value DESC

这个查询有2个reducer,每个结果如下
这里写图片描述
4.sort by排序字段设置类型
变量类型通常被认为是字符串类型,意味着数值型的数据将会以字母表顺序排序。为了克服这个方面,需要在使用sort by之前使用castselect语句中转换类型。

FROM (FROM (FROM src
            SELECT TRANSFORM(value)
            USING 'mapper'
            AS value, count) mapped
      SELECT cast(value as double) AS value, cast(count as int) AS count
      SORT BY value, count) sorted
SELECT TRANSFORM(value, count)
USING 'reducer'
AS whatever

hive中的distribute by是控制在map端如何拆分数据给reduce端的

Order by 能够预期产生完全排序的结果,但是它是通过只用一个reduce来做到这点的。所以对于大规模的数据集它的效率非常低。在很多情况下,并不需要全局排序,此时可以换成Hive的非标准扩展sort by。Sort by为每个reducer产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,通常是为了进行后续的聚集操作。Hive的distribute by 子句可以做这件事。

查询学生信息,结果按学号全局有序
    select * from student order by sno;
查询学生信息,结果区分性别按年龄有序
参考 https://blog.csdn.net/ggwxk1990/article/details/78338595
    set mapred.reduce.tasks=2
    select * from student distribute by sex sort by sage;

1.6、Join查询,join只支持等值连接

查询每个学生及其选修课程的情况
  hive> select student.*,sc.* 
  from student 
  join sc on (student.Sno =sc.Sno);
查询学生的各门得分情况。
  hive>select student.Sname,course.Cname,sc.Grade 
      from student 
      join sc on student.Sno=sc.Sno 
      join course on sc.cno=course.cno;
查询选修2号课程且成绩在90分以上的所有学生。
    select student.Sname,sc.Grade 
    from student 
    join sc on student.Sno=sc.Sno where  sc.Cno=2 and sc.Grade>90;

1.7、LEFT,RIGHT 和 FULL OUTER JOIN

查询所有学生的信息,如果在成绩表中有成绩,则输出成绩表中的课程号
  select sc.cno from student left outer join  sc on student.Sno=sc.Sno;

1.8、LEFT SEMI JOIN Hive当前没有实现 IN/EXISTS 子查询,可以用 LEFT SEMI JOIN 重写子查询语句。


重写以下子查询
  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)

查询与"刘晨"在同一个系学习的学生
  hive> select s1.Sname from student s1 
  left semi join student s2 
  on s1.Sdept=s2.Sdept and s2.Sname='刘晨';

注意比较:
select * from student s1 left join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';
select * from student s1 right join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';
select * from student s1 inner join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';
select * from student s1 left semi join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';
select s1.Sname from student s1 right semi join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';

猜你喜欢

转载自blog.csdn.net/wuxintdrh/article/details/81735303