hive sql 基本练习

表的结构

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;


//selct from 这个英文语句就可以看出是先做 from后面的操作,然后再做select操作将其取出来,还是要按照歪果仁的思维来思考问题

查询全体学生的学号与姓名

select Sno, Sname from student;
查询选修了课程的学生姓名
select Sname from student s where s.Sdept is not null;
----hive的group by 和集合函数


查询学生的总人数
select count(*) from student;    // count是数行的,sum是求数据的和
计算1号课程的学生平均成绩
select avg(s.Grade) from sc s where s.Grade = 1;
查询各科成绩平均分

查询选修1号课程的学生最高分数

    select grade from sc where cno=1  sort by grade limit 1 //xx这里是不正确的 因为sort是局部的并不是全局的

(注意比较:select * from sc where Cno=1 sort by Grade

 select Grade from sc where Cno=1 order by Grade)    //order 会将reduce数量强行改为一个,所以order by是全局的,但是大数据里面用order by 不利于效率

求各个课程号及相应的选课人数 
    select cno count(1) from sc group by con //count(1)和count(*)的作用都是一致的,前者稍微快一点
    
查询选修了3门以上的课程的学生学号

    select sno from sc where count(1)>3 group by son //xx 这是错的,Having是先分组(这里的分组指的是group by)在进行筛选,而where是先筛选再进行分组。这里是先分组再进行的筛选所以要写成

    select sno from sc group by son Having count(1)>3 

----hive的Order By/Sort By/Distribute By  //sql中只有Order By

Order By ,在strict 模式下(hive.mapred.mode=strict),order by 语句必须跟着limit语句,但是在nonstrict下就不是必须的,这样做的理由是必须有一个reduce对最终的结果进行排序,如果最后输出的行数过多,一个reduce需要花费很长的时间。

查询学生信息,结果按学号全局有序
hive> set hive.mapred.mode=strict;   <默认nonstrict>
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=在sort by可以指定,在用sort by的时候,如果没有指定列,它会随机的分配到不同的reduce里去。distribute by 按照指定的字段对数据进行划分到不同的输出reduce中 

  此方法会根据性别划分到不同的reduce中 ,然后按年龄排序并输出到不同的文件中。


查询学生信息,结果区分性别按年龄有序

hive> set mapred.reduce.tasks=2;(过时)    //set mapreduce.job.reduces=2 在hadoop2中有些参数名称过时了,例如原来的mapred.reduce.tasks改名为mapreduce.job.reduces了,当然,这两个参数你都可以使用,只是第一个参数过时了。
  hive> insert overwrite local directory '/home/hadoop/out' 

select * from student distribute by Sex sort by Sage;

补充:

保存select查询结果的几种方式:
1、将查询结果保存到一张新的hive表中
create table t_tmp
as
select * from t_p;

2、将查询结果保存到一张已经存在的hive表中
insert into  table t_tmp
select * from t_p;

3、将查询结果保存到指定的文件目录(可以是本地,也可以是hdfs)
insert overwrite local directory '/home/hadoop/test'

select * from t_p;

4、保存到hdfs

insert overwrite directory '/aaa/test'
select * from t_p;

----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; //join两个表
查询选修2号课程且成绩在90分以上的所有学生。
  
----LEFT,RIGHT 和 FULL OUTER JOIN (全外连接接) inner join  //内连接就是求交集没有交集的地方不会显示,要求严格些
查询所有学生的信息,如果在成绩表中有成绩,则输出成绩表中的课程号
  

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

//HIVE 的semi join效率比innerjoin要高些

重写以下子查询
  SELECT a.key, a.value
  FROM a
  WHERE a.key in
   (SELECT b.key
    FROM B);


查询与“刘晨”在同一个系学习的学生

  hive> select s1.Sname from student s1 left semi join student s2 on s1.Sdept=s2.Sdept and s2.Sname='刘晨';

hive 里面的内置函数


你可能感兴趣的:(hive)