--1.学生表
Student(S,Sname,Sage,Ssex) --S 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别
--2.课程表
Course(C,Cname,T) --C --课程编号,Cname 课程名称,T 教师编号
--3.教师表
Teacher(T,Tname) --T 教师编号,Tname 教师姓名
--4.成绩表
SC(S,C,score) --S 学生编号,C 课程编号,score 分数
use hplx;
hive版
建表:
create table student(sid string,sname string,sage int,ssex string) row format delimited fields terminated by '\t';
create table course(cid string,cname string,tid string) row format delimited fields terminated by '\t';
create table teacher(tid string,tname string) row format delimited fields terminated by '\t';
create table sc(sid string,cid string,score int) row format delimited fields terminated by '\t';
生成数据:
vi /usr/local/etc/student
01 赵雷 19900101 男
02 钱电 19901221 男
03 孙风 19900520 男
04 李云 19900806 男
05 周梅 19911201 女
06 吴兰 19920301 女
07 郑竹 19890701 女
08 王菊 19900120 女
vi /usr/local/etc/course
01 语文 02
02 数学 01
03 英语 03
vi /usr/local/etc/teacher
01 张三
02 李四
03 王五
vi /usr/local/etc/sc
01 01 80
01 02 90
01 03 99
02 01 70
02 02 60
02 03 80
03 01 80
03 02 80
03 03 80
04 01 50
04 02 30
04 03 20
05 01 76
05 02 87
06 01 31
06 03 34
07 02 89
07 03 98
导数据到hive:
load data local inpath '/usr/local/etc/student' into table student;
load data local inpath '/usr/local/etc/course' into table course;
load data local inpath '/usr/local/etc/teacher' into table teacher;
load data local inpath '/usr/local/etc/sc' into table sc;
经典50题
-- 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数
SELECT
student.*
FROM
student
LEFT JOIN
sc aa ON student.s = aa.s AND aa.c = '01'
LEFT JOIN
sc bb ON student.s = bb.s AND bb.c = '02'
WHERE
aa.score > bb.score;
hive:
SELECT sss.sid
FROM
(
SELECT sid sid,sum(c1) s1,sum(c2) s2
FROM
(
SELECT sid sid,
case WHEN cid=1 THEN score ELSE -1 END c1,
case WHEN cid=2 THEN score ELSE -1 END c2
FROM sc
) scc
WHERE c1!=-1 or c2!=-1
GROUP BY sid
) sss
WHERE s1!=-1 AND s2!=-1 AND s1>s2;
select a.* ,b.s_score as 01_score,c.s_score as 02_score from
student a
join score b on a.s_id=b.s_id and b.c_id='01'
left join score c on a.s_id=c.s_id and c.c_id='02' or c.c_id = NULL
where b.s_score>c.s_score
原文:https://blog.csdn.net/Z_Date/article/details/83998030
-- 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
SELECT
student.*
FROM
student
LEFT JOIN
sc aa ON student.s = aa.s AND aa.c = '01'
LEFT JOIN
sc bb ON student.s = bb.s AND bb.c = '02'
WHERE
aa.score < bb.score;
-- 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select student.s,sname,avg(score) avgs
from student left join sc on student.s=sc.s
group by student.s
having avgs>=60;
-- 4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
select student.s,sname,avg(score) avgs
from student left join sc on student.s=sc.s
group by student.s
having avgs<60;
-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select student.s,sname,count(*) num,sum(score) sums
from student left join sc on student.s=sc.s
group by student.s;
-- 6、查询"李"姓老师的数量
select count(*) num from teacher where tname like '李%';
-- 7、查询学过"张三"老师授课的同学的信息
select student.*
from student left join sc on student.s=sc.s
left join course on sc.c=course.c
left join teacher on course.t=teacher.t
where teacher.tname='张三';
-- 8、查询没学过"张三"老师授课的同学的信息
select *
from student aa
where not exists(
select student.*
from student left join sc on student.s=sc.s
left join course on sc.c=course.c
left join teacher on course.t=teacher.t
where teacher.tname='张三' and student.s=aa.s);
hive:
select notstudy.sid,student.sname
from
(
select all.sid sid
from
(
select distinct sid from sc?
) all
left join
(
select sid sid
from
(
select course.cid c
from
(
select tid from teacher where tname='张三'
) t
join course
on t.tid=course.tid
) c
join sc
on sc.cid=c.c
) s
on s.sid=all.sid
where s.sid is null
) notstudy
join student
on student.sid=notstudy.sid;
-- 9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
select student.*
from student join sc aa on student.s=aa.s and aa.c='01'
join sc bb on student.s=bb.s and bb.c='02';
-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
select student.*
from student left join sc aa on student.s=aa.s and aa.c='01'
left join sc bb on student.s=bb.s and bb.c='02'
where aa.c is not null and bb.c is null;
-- 11、查询没有学全所有课程的同学的信息
set @num =(select count(*) from course);
select student.*
from student left join sc on student.s=sc.s
group by student.s
having count(score)=@num;
-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息
select student.*
from student left join sc aa on student.s=aa.s
where exists(select * from sc where aa.c=sc.c)
group by student.s;
select student.*
from student left join sc on student.s=sc.s
where sc.c in (select c from sc where s='01')
group by student.s;
hive:
select stu.sid
from
(
select other.s sid,other.c cid
from
(
select cid from sc where sid=01
) s01
join
(
select sid s,cid c from sc where sid!=01
) other
on other.c=s01.cid
) stu
group by stu.sid
having count(cid)>=1;
-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息
set @num=(select count(*) from sc where sc.s='01');
select student.*
from student left join sc aa on student.s=aa.s
where exists(select * from sc where aa.c=sc.c)
group by student.s
having count(*)=@num and student.s!='01';
hive:
select stu.sid,count(cid)
from
(
select other.s sid,other.c cid
from
(
select cid from sc where sid=1
) s01
left join
(
select sid s,cid c from sc where sid!=01
) other
on other.c=s01.cid
) stu
group by stu.sid
having count(cid)=3;
-- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名
select sname
from student aa
where not exists(
select *
from sc left join course on sc.c=course.c
left join teacher on course.t=teacher.t
where teacher.tname='张三' and aa.s=sc.s);
select sname
from student
where s not in(select s
from sc left join course on sc.c=course.c
left join teacher on course.t=teacher.t
where teacher.tname='张三' );
-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select student.s,sname,avg(score) avgs
from student left join sc on student.s=sc.s
group by student.s
having sum(case when score<60 then 1 else 0 end)>=2;
-- 16、检索"01"课程分数小于60,按分数降序排列的学生信息
select student.*
from student left join sc on student.s=sc.s
where sc.c='01' and sc.score<60
order by score desc;
-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select sc.*,avgs
from sc left join(select s,avg(score) avgs from sc group by s) as c on sc.s=c.s;
-- 18、查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select sc.c,cname,max(score) maxs,min(score) mins,avg(score) avgs,
sum(case when score>=60 then 1 else 0 end)/count(score) rate1,
sum(case when score>=70 and score<80 then 1 else 0 end)/count(score) rate2,
sum(case when score>=80 and score<90 then 1 else 0 end)/count(score) rate3,
sum(case when score>=90 then 1 else 0 end)/count(score) rate4
from sc left join course on sc.c=course.c
group by sc.c;
-- 19、按各科成绩进行排序,并显示排名
set @rank=0;
select c.*,@rank:=@rank+1 rank
from
(select *
from sc
order by score desc) as c;
-- 20、查询学生的总成绩并进行排名
set @rank=0;
select c.*,@rank:=@rank+1
from
(select s,c,sum(score) sums from sc
group by sc.s
order by sum(score) desc)as c;
-- 21、查询不同老师所教不同课程平均分从高到低显示
select teacher.t,tname,course.c,avg(score) avgs
from sc left join course on sc.c=course.c
left join teacher on course.t=teacher.t
group by teacher.t
order by avgs desc;
-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
select student.*,score
from student left join sc aa on student.s=aa.s
where (select sum(case when score>aa.score then 1 else 0 end) from sc where sc.c=aa.c) in (1,2);
-- 23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select sc.c,cname,
sum(case when score<60 then 1 else 0 end)/count(*) '[0-60]',
sum(case when score>=60 and score <70 then 1 else 0 end)/count(*) '[60-70]',
sum(case when score>=70 and score<85 then 1 else 0 end)/count(*) '[70-85]',
sum(case when score>=85 then 1 else 0 end)/count(*) '[85-100]'
from sc left join course on sc.c=course.c
group by sc.c;
-- 24、查询学生平均成绩及其名次
set @rank=0;
select c.*,@rank:=@rank+1 rank
from
(select s,c,avg(score) avgs from sc group by s order by avgs desc) as c;
-- 25、查询各科成绩前三名的记录
select student.*, score
from student
left join sc aa
on student.s=aa.s
where (select sum(case when score>aa.score then 1 else 0 end)
from sc
where sc.c=aa.c) in (0,1,2);
-- 26、查询每门课程被选修的学生数
select count(score) num from sc group by sc.c;
-- 27、查询出只有两门课程的全部学生的学号和姓名
select student.s,sname
from student left join sc on student.s=sc.s
group by student.s
having count(score)=2;
-- 28、查询男生、女生人数
select ssex,count(*) num from student group by ssex;
-- 29、查询名字中含有"风"字的学生信息
select student.* from student where sname like "%风%";
-- 30、查询同名同性学生名单,并统计同名人数
select student.*,count(*)
from student
group by sname,ssex
having count(*)>1;
-- 31、查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)
select * from student where year(sage)=1990;
-- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号
select c,avg(score) avgs
from sc
group by c
order by avgs desc,c;
-- 33、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
select student.s,sname,avg(score) avgs
from student left join sc on student.s=sc.s
group by student.s
having avgs>=85;
-- 34、查询课程名称为"数学",且分数低于60的学生姓名和分数
select sname,score
from student left join sc on student.s=sc.s
left join course on sc.c=course.c
where cname='数学' and score<60;
-- 35、查询所有学生的课程及分数情况;
select * from sc;
-- 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;
select sname,cname,score
from student aa left join sc on aa.s=sc.s
left join course on sc.c=course.c
where (select sum(case when score>70 then 1 else 0 end) from sc where aa.s=sc.s)>=1;
-- 37、查询不及格的课程
select * from sc where score<60;
-- 38、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名;
select student.s,sname
from student left join sc on student.s=sc.s
where c='01' and score>=80;
-- 39、求每门课程的学生人数
select c,count(*) num from sc group by c;
-- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
set @rank=0;
select c.* from
(select student.*,score
from student left join sc on student.s=sc.s
left join course on sc.c=course.c
left join teacher on teacher.t=course.t
where tname='张三'
order by score desc) as c
where (@rank:=@rank+1)=1;
-- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select sc.*
from sc left join sc aa on sc.s=aa.s
where sc.c!=aa.c and sc.score=aa.score;
-- 42、查询每门功成绩最好的前两名
select * from sc aa
where(select sum(case when score>aa.score then 1 else 0 end) from sc where sc.c=aa.c) in(0,1);
hive:
select s.sid,s.cid,s.score
from
(
select sid,cid,score,row_number()over(partition by cid order by score desc) rank
from sc
) s
where s.rank<=2;
-- 43、统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select c,count(score) num
from sc
group by c
having num>5
order by num desc;
-- 44、检索至少选修两门课程的学生学号
select s
from sc
group by s
having count(score)>1;
-- 45、查询选修了全部课程的学生信息
set @num=(select count(*) from course);
select student.*
from student left join sc on student.s=sc.s
group by student.s
having count(score)=@num;
hive:
select student.sid,student.sname
from
student
join
(
select s.sid
from
(
select count(cid) c from course
) cou
join
(
select sid,count(cid) c from sc group by sid
) s
on cou.c=s.c
) o
on student.sid=o.sid;
-- 46、查询各学生的年龄
select student.*,(year(now())-year(sage)) age from student;
-- 47、查询本周过生日的学生
select *
from student
where date_add(sage,interval (year(now())-year(sage)) year) between
date_add(curdate(),interval -weekday(curdate()) day) and
date_add(curdate(),interval 6-weekday(curdate()) day);
-- 48、查询下周过生日的学生
select *
from student
where date_add(sage,interval (year(now())-year(sage)) year) between
date_add(curdate(),interval 7-weekday(curdate()) day) and
date_add(curdate(),interval 13-weekday(curdate()) day);
-- 49、查询本月过生日的学生
select *
from student
where month(sage)=month(now());
-- 50、查询下月过生日的学生
select *
from student
where month(sage)=month(now())+1;
hive:
--9.查询所有课程成绩小于60分的同学的学号、姓名
select stu.sid,student.sname
from
(
select lt60.sid sid
from
(
select s.sid sid,count(s.sid) c
from
(
select sid from sc where score<=60
) s
group by s.sid
) lt60
join
(
select sid sid,count(1) c
from sc?
group by sid
) all
on lt60.sid=all.sid and lt60.c=all.c
) stu
join student
on stu.sid=student.sid;
ref:
https://blog.csdn.net/zhaolq1024?t=1