SQL强化训练经典50题 及hive版

--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

你可能感兴趣的:(SQL强化训练经典50题 及hive版)