项目实战从0到1之hive(13)hive经典50题

一.建表和加载数据
1.student表
create table if not exists student(s_id int,s_name string,s_birth string,s_sex string)
row format delimited
fields terminated by ','
;
load data local inpath '/root/data.txt' into table student;

2.course表
create table if not exists course(c_id int,c_course string,t_id int)
row format delimited
fields terminated by ','
;
load data local inpath '/root/data.txt' into table course;

3.teacher表
create table if not exists teacher(t_id int,t_name string)
row format delimited
fields terminated by ','
;
load data local inpath '/root/data.txt' into table teacher;
4.score表
create table if not exists score(s_id int,c_id int, s_score DOUBLE)
row format delimited
fields terminated by ','
;
load data local inpath '/root/data.txt' into table score;

二.查询"01"课程比"02"课程成绩高的学生的信息及课程分数?
答案①:
select stu.*,c.*
from student stu
join score a on a.c_id = '01' and a.s_id= stu.s_id
left join score b on b.c_id = '02' and b.s_id= stu.s_id
join score c on c.s_id= stu.s_id
where a.s_score > b.s_score or b.s_score is null
;
答案②:
select stu.*,c.*
from student stu
left join score a on a.c_id = '02' and a.s_id= stu.s_id
join score b on b.c_id = '01' and b.s_id= stu.s_id
join score c on c.s_id= stu.s_id
where a.s_score < b.s_score or a.s_score is null
;
三.查询"01"课程比"02"课程成绩低的学生的信息及课程分数:
答案①:
select stu.*,c.*
from student stu
join score a on a.c_id = '02' and a.s_id= stu.s_id
left join score b on b.c_id = '01' and b.s_id= stu.s_id
join score c on c.s_id= stu.s_id
where a.s_score > b.s_score or b.s_score is null
;
答案②:
select stu.*,c.*
from student stu
left join score a on a.c_id = '01' and a.s_id= stu.s_id
join score b on b.c_id = '02' and b.s_id= stu.s_id
join score c on c.s_id= stu.s_id
where a.s_score < b.s_score or a.s_score is null
;
总结:对于二题和三题的查询连接的方法:谁大就把谁放在左边,谁小就把谁舍弃。
四.查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩?
答案①:
select 
a.s_id,stu.s_name,avg(a.s_score) as avgscore
from score a
join student stu on a.s_id = stu.s_id
group by a.s_id,stu.s_name
having avgscore >= 60
;
答案②:
select 
a.s_id,stu.s_name,avg(a.s_score)>=60
from score a
join student stu on a.s_id = stu.s_id
group by a.s_id,stu.s_name
;
五.查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩?
答案①:
select 
a.s_id,stu.s_name,avg(a.s_score) as avgscore
from score a
join student stu on a.s_id = stu.s_id
group by a.s_id,stu.s_name
having avgscore < 60
union all
select stu.s_id,stu.s_name,NULL as avgscore
from student stu
left join score a on stu.s_id = a.s_id
where a.s_score is null
;
六.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
答案:
select stu.s_id,stu.s_name,count(sc.s_id) as totalSubjects,sum(sc.s_score) as sumScores     
from student stu left join score sc on stu.s_id=sc.s_id
group by stu.s_id,stu.s_name;
七.查询"李"姓老师的数量?
select count(1)from teacher where t_name like '李%';
八.查询学过"张三"老师授课的同学的信息?
select distinct stu.*
from student stu 
join score sc on stu.s_id=sc.s_id
join course co on sc.c_id=co.c_id
join teacher te on co.t_id =te.t_id
where te.t_name='张三';
九.查询没学过"张三"老师授课的同学的信息?
select *
from student stu
join teacher te on te.t_name='张三'
join course co on te.t_id=co.t_id
left join score sc on stu.s_id=sc.s_id and co.c_id=sc.c_id
where sc.s_score is null;
十.查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息?
select stu.*,sc.*
from student stu,score sc,score sc1
where stu.s_id=sc.s_id and stu.s_id=sc1.s_id
and sc.c_id=1 and sc1.c_id=2;
十一.查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息:
select stu.*
from student stu
join score sc on sc.s_id =stu.s_id and sc.c_id = '01' 
where not exists (select 1 from score sc1 where sc1.c_id = '02' and stu.s_id = sc1.s_id)
;
十二.查询没有学全所有课程的同学的信息?
select distinct stu.*
from student stu
join score sc
left join course co
on stu.s_id=sc.s_id and sc.c_id=co.c_id
where sc.s_score is null;
十三.查询至少有一门课与学号为"01"的同学所学相同的同学的信息?
select distinct stu.*
from student stu
join score sc on stu.s_id=sc.s_id
where stu.s_id <> 1 and sc.c_id in
(select c_id from score where s_id=1);

十四.查询和"01"号的同学学习的课程完全相同的其他同学的信息?
select 

十五.查询没学过"张三"老师讲授的任一门课程的学生姓名?
select stu.*
from student stu
join teacher te on te.t_name = '张三'
join course co on co.t_id = te.t_id
left join score sc on sc.c_id = co.c_id and sc.s_id = stu.s_id
where sc.s_score is null;
十六.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩?
select 
*
from student stu 
join score sc on sc.s_id = stu.s_id
where sc.s_score < 60
;

十七.检索"01"课程分数小于60,按分数降序排列的学生信息?
select *
from student stu
join score sc on sc.s_id = stu.s_id
where sc.c_id = 1 and sc.s_score < 60
order by sc.s_score desc;
十八.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩?
select *,
round(avg(sc.s_score) over(distribute by sc.s_id),2) as avg1
from score sc
order by avg1 desc,sc.s_score desc;
总结:在这里啊,round是hive的内置函数,其功能是四舍五入。
十九..查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率:
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90?
select 
co.c_id,
co.c_course,
max(sc.s_score),
min(sc.s_score),
round(avg(sc.s_score),3),
round(sum(case when sc.s_score >=60 then 1 else 0 end)/count(1) *100,3) as `及格率`,
round(sum(case when sc.s_score between 70 and 79 then 1 else 0 end)/count(1) *100,3) as `中等率`,
round(sum(case when sc.s_score between 80 and 89 then 1 else 0 end)/count(1) *100,3) as `优良率`,
round(sum(case when sc.s_score>=90 then 1 else 0 end)/count(1) *100,3) as `优秀率`
from score sc
join course co on sc.c_id=co.c_id
group by co.c_id,co.c_course;

二十.按各科成绩进行排序,并显示排名:– row_number() over()分组排序功能?
select *,
row_number() over(distribute by c_id sort by s_score desc) from score;
二十一.查询学生的总成绩并进行排名?
select s_id,sum(s_score) as sumScores
from score
group by s_id
order by sumScores desc;
二十二:查询不同老师所教不同课程平均分从高到低显示?
select t_id,sc.c_id,round(avg(sc.s_score),2) as avgscore
from score sc
join course co on sc.c_id=co.c_id
group by t_id,sc.c_id
order by t_id,avgscore desc;
二十三.查询所有课程的成绩第2名到第3名的学生信息及该课程成绩?
select *
from ( select *,
row_number() over(distribute by c_id sort by s_score desc) as rm
from score ) a
where a.rm between 2 and 3;
二十四.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比?
select c_id,
sum(case when s_score>=85 then 1 else 0 end) as 85score,
sum(case when s_score between 70 and 84 then 1 else 0 end) as 70score,
sum(case when s_score between 60 and 69 then 1 else 0 end) as 60score,
sum(case when s_score<60 then 1 else 0 end) as 0score,
count(1) as totalscore
from score group by c_id;
二十五.查询学生平均成绩及其名次?
select *,
row_number() over(sort by a.avgscore desc) as rm
from (
select s_id,round(avg(s_score),2) as avgscore
from score group by s_id) a;
二十六.查询各科成绩前三名的记录三个语句?
select *
from (
select *,
row_number() over(distribute by c_id sort by s_score desc) as rm,
rank() over(distribute by c_id sort by s_score desc) as rk,
dense_rank() over(distribute by c_id sort by s_score desc) as drk
from score) a where a.rm<4;
二十七.查询每门课程被选修的学生数?
select c_id,count(1) as `学生人数`
from score
group by c_id;
二十八.查询出只有两门课程的全部学生的学号和姓名?
select stu.s_id,stu.s_name
from student stu
join score sc on sc.s_id=stu.s_id
group by stu.s_id,stu.s_name
having count(1)=2;
二十九.查询男生、女生人数?
select s_sex,count(1) as totalstu
from student 
group by s_sex;
三十.查询名字中含有"风"字的学生信息?
select *
from student
where s_name like '%风%' ;
三十一.查询同名同性学生名单,并统计同名人数?
select s_name,s_sex,count(1) as totalstu
from student
group by s_name,s_sex
having totalstu>1;
三十二.查询1990年出生的学生名单?
select *
from student
where s_birth like '1990%';
select *
from student
where substr(s_birth,0,4)='1990';
三十三.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列?
select c_id,round(avg(s_score),2) as avgscore
from score
group by c_id
order by avgscore desc,c_id asc;
三十四:查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩?
select stu.s_name,avg(sc.s_score) as avgscore
from student stu 
join score sc on stu.s_id=sc.s_id
group by stu.s_id,stu.s_name
having avgscore>85;
三十五:查询课程名称为"数学",且分数低于60的学生姓名和分数?
select stu.s_name,sc.s_score
from student stu
join score sc on stu.s_id=sc.s_id
join course co on sc.c_id=co.c_id and co.c_course='数学'
where sc.s_score<60;
三十六:查询所有学生的课程及分数情况?
select *
from student stu
join score sc on stu.s_id=sc.s_id
right join course co on sc.c_id=co.c_id
;
三十七:查询任何一门课程成绩在70分以上的学生姓名、课程名称和分数?
select stu.s_name,co.c_course,sc.s_score
from student stu
join score sc on stu.s_id=sc.s_id
join course co on sc.c_id=co.c_id
group by stu.s_id,stu.s_name,co.c_course,sc.s_score  having min(sc.s_score)>=70;
三十八:查询课程不及格的学生?
select stu.*
from student stu
join score sc on stu.s_id=sc.s_id
where sc.s_score<60;
三十九:查询课程编号为01且课程成绩在80分以上的学生的学号和姓名?
select stu.s_id,stu.s_name,sc.c_id,sc.s_score
from student stu
join score sc on stu.s_id=sc.s_id
where c_id=1 and s_score>=80;
四十:每门课程的学生人数?
select sc.c_id,co.c_course,count(1) as stunum
from score sc
join course co on sc.c_id=co.c_id
group by sc.c_id,co.c_course;
四十一:查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩?
select *
from (
select
dense_rank() over(distribute by sc.c_id sort by sc.s_score desc) drk
from score sc
join course co on sc.c_id=co.c_id
join teacher te on co.t_id=te.t_id
where te.t_name='张三') aa
where aa.drk=1;
四十二:查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩?
①select distinct sc.s_id,sc.c_id,sc.s_score
from score sc,score sc1
where sc.c_id<>sc1.c_id and sc.s_score=sc1.s_score and sc.s_id=sc1.s_id;
②select distinct sc.s_id,sc.c_id,sc.s_score
from score sc,score sc1
where sc.c_id !=sc1.c_id and sc.s_score=sc1.s_score and sc.s_id=sc1.s_id;
四十三:查询每门课程成绩最好的前三名?
select *
from (select *,
row_number() over(distribute by c_id sort by s_score desc) rn
from score) aa
where aa.rn<=3;
四十四:统计每门课程的学生选修人数(超过5人的课程才统计)?
select c_id,count(*) as stunum
from score
group by c_id
having stunum>5
order by c_id asc,stunum desc;
四十五:检索至少选修两门课程的学生学号?
select s_id,count(1) as coursenum
from score
group by s_id having coursenum >=2;
四十六:查询选修了全部课程的学生信息?
select stu.s_id,stu.s_name
from student stu
join score sc on stu.s_id=sc.s_id
left join course co on sc.c_id=co.c_id
group by stu.s_id,stu.s_name
having sum(case when sc.s_score is null then 1 else 0 end)=0;
四十七:查询各学生的年龄(周岁)?
select 
s_birth,
year(current_date())-year(s_birth)-
(case 
when month(current_date())>month(s_birth)
then 0
when month(current_date())=month(s_birth)
and
day(current_date())>=day(s_birth)
then 0 else 1 end)
from student;
四十八:查询本周过生日的学生?
select *
from student
where weekofyear(s_birth)=weekofyear(current_date());
四十九:查询下周过生日的学生?
select *
from student
where weekofyear(s_birth)=weekofyear(current_date())+1;
四十九:查询上周过生日的学生?
select *
from student
where weekofyear(s_birth)=weekofyear(current_date())-1;
五十:查询本月过生日的学生?
select *
from student
where month(s_birth)=month(current_date());
五十:查询上月过生日的学生?
select *
from student 
where month(s_birth)=month(current_date())-1;
五十:查询下月过生日的学生?
select *
from student 
where month(s_birth)=month(current_date())+1;
五十一:查询12月份过生日的学生?
①select *
from student
where month(s_birth)=12;

②select *
from student 
where substring(s_birth,4,2)=12;
作者:大码王

-------------------------------------------

个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!

如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•?ω•?)っ???!

原文地址:https://www.cnblogs.com/huanghanyu/p/13637636.html