通过学生-课程关系表,熟悉hive语句

1、在hive中创建以下三个表。

create table  student(Sno int,Sname string,Sex string,Sage int,Sdept string)row format delimited fields terminated by ','stored as textfile;
create table course(Cno int,Cname string) row format delimited fields terminated by ',' stored as textfile;
create table sc(Sno int,Cno int,Grade int)row format delimited fields terminated by ',' stored as textfile;
2、load数据到三个表中。
load data local inpath '/home/student.txt' overwrite into table student;
load data local inpath '/home/sc.txt' overwrite into table sc;
load data local inpath '/home/course.txt' overwrite into table course;

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

1,数据库
2,数学
3,信息系统
4,操作系统
5,数据结构
6,数据处理

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

3、hive的select
SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number]
  • 查询全体学生的学号与姓名
hive> select Sno,Sname from student;
Total MapReduce jobs = 1
  • 查询选修了课程的学生姓名
hive> select distinct Sname from student inner join sc on student.Sno=Sc.Sno;
Total MapReduce jobs = 2
3、hive的group by 和集合函数
在一个query里可以出现多个聚合函数,但是一个query语句里2个聚合函数只能有一个distinct。
hive.map.aggr控制我们怎样去聚合,默认值为false,如果设置为ture后,会在map任务里执行第一级别的聚合,通常这样会有 高的效率,但是需要更大的内存。
  • 查询学生的总人数
hive> select count(distinct Sno)count from student;
Total MapReduce jobs = 1
  • 计算1号课程的学生平均成绩
hive> select avg(distinct Grade) from sc where Cno=1;
  • 查询选修1号课程的学生最高分数
  select Grade from sc where Cno=1 sort by Grade desc limit 1;      
Total MapReduce jobs = 2      
  • 求各个课程号及相应的选课人数
hive> select Cno,count(1) from sc group by Cno;
Total MapReduce jobs = 1
  • 查询选修了3门以上的课程的学生学号
hive> select Sno from (select Sno,count(Cno)CountCno from sc group by Sno)a where a.CountCno>3;
Total MapReduce jobs = 1
hive> select Sno from sc group by Sno having count(Cno)>3; 
Total MapReduce jobs = 1
4、hive的Order By/Sort By/Distribute By/Cluster By
Order By ,在strict 模式下(hive.mapred.mode=strict),order by
语句必须跟着limit语句,但是在非strict下就不是必须的,这样做的理由是必须有一个reduce对最终的结果进行排序,如果最后输出的行数过多,一个reduce需要花费很长的时间。
hive> set hive.mapred.mode=strict;
hive> select Sno from student order by Sno;
FAILED: Error in semantic analysis: 1:33 In
strict mode, if ORDER BY is specified, LIMIT must also be specified.
Error encountered near token 'Sno'
Sort By,它通常发生在每一个redcue里,“order by” 和“sort by"的区别在于,前者能给保证输出都是有顺序的,而后者如果有多个reduce的时候只是保证了输出的部分有序。set mapred.reduce.tasks=<number>在sort by可以指定,在用sort by的时候,如果没有指定列,它会随机的分配到不同的reduce里去。
distribute by 按照指定的字段对数据进行划分到不同的输出reduce中 
此方法会根据性别划分到不同的reduce中 ,然后按年龄排序并输出到不同的文件中。
hive> set mapred.reduce.tasks=2;
hive> insert overwrite local directory '/home/hadoop/out' select * from student distribute by Sex sort by Sage;
Cluster By 能保证分配给同一个reduce的相同的列邻近,除distribute
by除完成的功能外。
5、Join
  • join只支持等值连接 e.g.
查询每个学生及其选修课程的情况
  • 如果join
    on的key值不是相同的话,会转化为2个map/reduc e.g. 如果key相同的话会转化为一个map/reduce
    job,由于第一个job的map/reduce的结果会缓冲起来,然后再跟第二个进行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;
Total MapReduce jobs =
2
  • LEFT,RIGHT 和 FULL
    OUTER 关键字用于处理 join 中空记录的情况。
hive> select student.Sname,sc.Cno from student left outer join sc on student.Sno=sc.Sno;
如果student的sno值对应的sc在中没有值,则会输出student.Sname
null.如果用right out join会保留右边的值,左边的为null。

Join 发生在WHERE 子句之前。如果你想限制 join 的输出,应该在 WHERE 子句中写过滤条件——或是在join 子句中写。这里面一个容易混淆的问题是表分区的情况:

SELECT a.val, b.val FROM a

LEFT OUTER JOIN b ON (a.key=b.key)

WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

会 join a 表到 b 表(OUTER JOIN),列出 a.val 和 b.val 的记录。WHERE 从句中可以使用其他列作为过滤条件。但是,如前所述,如果 b 表中找不到对应 a 表的记录,b 表的所有列都会列出NULL,包括 ds 列。也就是说,join 会过滤 b 表中不能找到匹配 a 表 join
key 的所有记录。这样的话,LEFT OUTER 就使得查询结果与 WHERE 子句无关了。解决的办法是在 OUTER JOIN 时使用以下语法:

SELECT a.val, b.val FROM a LEFT OUTER JOIN b

ON (a.key=b.key AND

b.ds='2009-07-07' AND

a.ds='2009-07-07')

这一查询的结果是预先在 join 阶段过滤过的,所以不会存在上述问题。这一逻辑也可以应用于 RIGHT 和 FULL 类型的 join 中。

Join 是不能交换位置的。无论是 LEFT 还是 RIGHT join,都是左连接的。

SELECT a.val1, a.val2, b.val, c.val

FROM a

JOIN b ON (a.key = b.key)

LEFT OUTER JOIN c ON (a.key = c.key)

先 join a 表到 b 表,丢弃掉所有join key 中不匹配的记录,然后用这一中间结果和 c 表做 join。这一表述有一个不太明显的问题,就是当一个 key 在 a 表和 c 表都存在,但是 b 表中不存在的时候:整个记录在第一次 join,即 a
JOIN b 的时候都被丢掉了(包括a.val1,a.val2和a.key),然后我们再和 c 表 join 的时候,如果c.key 与 a.key 或 b.key 相等,就会得到这样的结果:NULL,
NULL, NULL, c.val。
  • LEFT SEMI JOIN  是 IN/EXISTS 子查询的一种更高效的实现。Hive 当前没有实现 IN/EXISTS
    子查询,所以你可以用 LEFT SEMI JOIN 重写你的子查询语句。LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在
    ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。

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)

  • 如果2个join的表非常小的话,join的过程可能只在mapper中就可以完成。
  • 如果有两个表join on的值为buckets列,并且buckets数量相同的话,可以只在mapper阶段完成。e.g.
 SELECT /*+ MAPJOIN(b) */ a.key, a.value
FROM a join b on a.key = b.key
在mapper阶段,可以对b的值按buckets进行取值,a表的一个buckets取b表的一个buckets进行join,这样做并不是模式的,必须设置。
set hive.optimize.bucketmapjoin = true
  • 练习:
查询选修2号课程且成绩在90分以上的所有学生。
hive> select student.Sname,sc.Grade from student join sc on student.Sno=sc.Sno where  sc.Cno=2 and sc.Grade>90;
查询与“刘晨”在同一个系学习的学生
hive> select s1.Sname from student s1 left semi join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';
6、hive的优化
  • 好的模型设计事半功倍。
  • 解决数据倾斜问题。
  • 减少job数。
  • 设置合理的map reduce的task数,能有效提升性能。(比如,10w+级别的计算,用160个reduce,那是相当的浪费,1个足够)。
  • 了解数据分布,自己动手解决数据倾斜问题是个不错的选择。set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化有时不能适应特定业务背景,开发人员了解业务,了解数据,可以通过业务逻辑精确有效的解决数据倾斜问题。
  • 数据量较大的情况下,慎用count(distinct),count(distinct)容易产生倾斜问题。
  • 对小文件进行合并,是行至有效的提高调度效率的方法,假如所有的作业设置合理的文件数,对云梯的整体调度效率也会产生积极的正向影响。
  • 优化时把握整体,单个作业最优不如整体最优。

通过学生-课程关系表,熟悉hive语句的更多相关文章

  1. Hibernate 再接触 树状结构设计以及学生课程成绩表的设计

    1 树状结构的设计 package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax. ...

  2. Django 小实例S1 简易学生选课管理系统 11 学生课程业务实现

    Django 小实例S1 简易学生选课管理系统 第11节--学生课程业务实现 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 课程模块中,学生需要拥 ...

  3. Mysql学生管理系统:表的建立,外键一对多,多对多关系,中间关联表的建立

    学生管理系统 管理员注册/登录/注销 注册班级(班级详细信息) 注册学生信息 查看班级信息/查看老师资料 教师注册/注销  查看教师资料  查看学生资料  根据名称/班级/ 查看学生详细信息--支持模 ...

  4. 工作中常见的hive语句总结

    hive的启动: 1.启动hadoop2.开启 metastore 在开启 hiveserver2服务nohup hive --service metastore >> log.out 2 ...

  5. Django模型基础(三)——关系表的数据操作

    模型之间可以有三种表关系,即一对一,一对多和多对多.表关联之间的数据操作在Django中可以很方便的操作到.在模型中,表关联的字段类型是关联表的实例,而不是字段本身类型.关联字段在数据库中会在其后补上 ...

  6. EF架构~关系表插入应该写在事务里,但不应该是分布式事务

    回到目录 这个标题很有意思,关系表插入,就是说主表和外表键在插入时,可能会有同步插的情况,如在建立主表时,扩展表需要同步完成数据的初始化工作,而对于多表插入时,我们为了保证数据的一致性会针它写在事务中 ...

  7. SQL 存储过程(学生,课程表,选修表)

    SQL 存储过程(学生,课程表,选修表) 一.存储过程的分类 在SQL Server中存储过程分过两类: 1)系统存储过程("sp_"作为前缀) 2)用户自定义存储过程 二.创建和 ...

  8. SQL 触发器(学生,课程表,选修表)

    SQL 触发器(学生,课程表,选修表) 触发器是一种特殊类型的存储过程,它不由用户通过命令来执行,而是在用户对表执行了插入,删除或修改表中数据等操作时激活执行.可以这样形容:存储过程像一个遥控炸弹,我 ...

  9. MySQL数据库(3)_MySQL数据库表记录操作语句

    附: MYSQL5.7版本sql_mode=only_full_group_by问题 .查询当前sql_mode: select @@sql_mode .查询出来的值为: set @@sql_mode ...

随机推荐

  1. blog搬家须知

    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻. 地址:这里. 不过这里也是会同步更新的

  2. equals hashcode toString 方法的使用

    package com.wu.toString; import java.util.Date; import java.util.GregorianCalendar; /** * * @author ...

  3. 「模拟赛20190327」 第二题 DP+决策单调性优化

    题目描述 小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物. 小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是\(n\times m\)的,某些格 ...

  4. HDU-1754-I Hate It(线段树 单点更新 区间最大值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. 扩展jQuery---选中指定索引的文本

    <script type="text/javascript"> //1.扩展jQuery $.fn.selectRange = function (start, end ...

  6. js 封装一个均速动画函数

    //动画函数---任意一个元素移动到指定的目标位置 //element为元素 target为位置 function carToon(element, target) { //设置一个定时器让他循环去增 ...

  7. linux下使用文件IO监听GPIO中断

    完整的程序如下: #include<stdlib.h> #include<stdio.h> #include<string.h> #include<unist ...

  8. springMVC下载功能

    前台页面 <a href="download">下载</a> 后台代码 /** * 文件下载 * @param request * @return * @t ...

  9. git 各个区的区别

    Git有三大区(工作区.暂存区.版本库)以及几个状态(untracked.unstaged.uncommited) 把文件往Git版本库里添加的时候,是分两步执行的: 第一步是用 git add 把文 ...

  10. AC自动机例题

    P3808 [模板]AC自动机(简单版) [题目描述] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. #include<bits/stdc++.h> using name ...