SQL经典50题
Posted ZhengXixide
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL经典50题相关的知识,希望对你有一定的参考价值。
用到的表的介绍
student: sid(学生ID),sname(学生姓名),sage,ssex
course: cid(课程ID),cname,tid(教师ID)
teacher: tid,tname
sc:sid,cid,score
只是附上题目和代码,没有运行结果
1.查询"01"课程比"02"课程成绩高的学生的信息及课程分数 select * from (select t1.sid,class1,class2 from (select sid,score as class1 from sc where cid=‘01‘ )as t1 join (select sid,score as class2 from sc where cid=‘02‘) as t2 on t1.sid=t2.sid and t1.class1>t2.class2 )r left join student on r.sid=student.sid ; 1.1 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null ) select * from (select * from sc where cid=‘01‘)t1 left join (select * from sc where cid=‘02‘)t2 on t1.sid=t2.sid ; 1.2 查询同时存在01和02课程的情况 select * from (select * from sc where cid=‘01‘ )t1 join (select * from sc where cid=‘02‘ )t2 on t1.sid =t2.sid ; 1.3 查询选择了02课程但没有01课程的情况 select * from sc where cid=‘02‘ and sid not in ( select sid from sc where cid=‘01‘) ; 2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩 select t1.sid,t1.meanscore,student.sname from (select sid,avg(score)as meanscore from sc group by sid having avg(score)>=60 )t1 left join student on t1.sid=student.sid ; 3.查询在 SC 表存在成绩的学生信息 select distinct student.* from sc join student on sc.sid=student.sid ; 4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的成绩总和 select r.*,student.sname from (select sid, count(distinct cid) as qcourse,sum(score)as sumscore from sc group by sid )r left join student on r.sid=student.sid ; 5.查询「李」姓老师的数量 select count(*) from teacher where tname like (‘李%‘) ; 6.查询学过「张三」老师授课的同学的信息 select student.* from (select * from teacher where tname= ‘张三‘ )t1 left join course on t1.tid=course.tid left join sc on course.cid=sc.cid left join student on sc.sid=student.sid ; @7.查询没有学全所有课程的同学的信息 select student.*,qcourse from (select sid,count(distinct cid) as qcourse from sc group by sid having count(distinct cid)<(select count(distinct cid) from course) ) left join student on sc.sid=student.sid ; @8.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息 select student.* from sc join student on sc.sid=student.sid where sc.cid in (select cid from sc where sid =‘01‘ ) and sc.sid !=‘01‘ group by sc.sid ; @9.查询和" 01 "号的同学学习的课程完全相同的其他同学的信息 10.查询没学过"张三"老师讲授的任一门课程的学生姓名 select sname from student where sid not in(select sid from sc left join course on sc.cid=course.cid left join teacher on course.tid=teacher.tid where teacher.tname !=‘张三‘) ; 11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 select t1.*,student.sname from (select sid,avg(score)as meanscore from sc where sid in (select sid,count(distinct cid) from sc where score<60 group by sid having count(distinct cid)>=2) )t1 left join student on t1.sid=student.sid ; 12.检索" 01 "课程分数小于 60,按分数降序排列的学生信息 select student.*,t1.score from (select * from sc where cid=‘01‘ and score<60 )t1 left join student on t1.sid=student.sid order by t1.score desc ; 13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 select sc.*,t1.meanscore from sc left join (select sid,avg(score) as meanscore from sc group by cid )t1 on sc.sid=t1.sid order by t1.meanscore ; 14.查询各科成绩最高分、最低分和平均分,以如下形式显示: 课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序 排列 select cid as ‘课程 ID‘, count(sid) as ‘课程人数‘, max(score) as ‘最高分‘, min(score) as ‘最低分‘, avg(score) as ‘平均分‘, cast(cast sum(及格) as double)/(cast count(sid) as double) as ‘及格率‘, SUM(中等) / COUNT(sid) AS ‘中等率‘, SUM(优良) / COUNT(sid) AS ‘优良率‘, SUM(优秀) / COUNT(sid) AS ‘优秀率‘ from (select *, case when score >=60 then 1 else 0 end as ‘及格‘, case when score>=70 and score<80 then 1 else 0 end as ‘中等 ‘, case when score >=80 and score<90 then 1 else 0 end as ‘优良‘, case when score >=90 then 1 else 0 end as ‘优秀‘ from sc )a group by cid order by count(sid)desc,cid ; @15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺 select a.*,count(a.score) as ‘排名‘ from sc a left join sc b on a.sid=b.sid and a.score < b.score group by a.cid,a.sid,a.score order by a.cid ; --用sc中的score和自己进行对比,来计算“比当前分数高的分数有几个”。 @15.1 按各科成绩进行行排序,并显示排名, Score 重复时合并名次 select a.*,count(b.score)+1 as ‘排名‘ from sc a left join sc b on a.sid=b.sid and a.score < b.score group by a.cid,a.sid,a.score order by a.cid ; @16.查询学生的总成绩,并进行排名,总分重复时保留名次空缺 select a.*,@rank:=@rank+1 as rank from (select sid, sum(score) from sc group by sid order by sum(score)desc )a, (select @rank:=0 )b ; 17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比 select a.*,course.cname from (select cid, sum(case when score>=85 and score <=100 then 1 else 0 end )/count(distinct sid) as ‘[100-85]‘, sum(case when score>=70 and score <85 then 1 else 0 end )/count(distinct sid) as ‘[85-75]‘, sum(case when score>=60 and score <70 then 1 else 0 end )/count(distinct sid) as ‘[70-60]‘, sum(case when score <60 then 1 else 0 end )/count(distinct sid) as ‘[60-0]‘ from sc group by cid )a left join course on a.cid =course.cid ; 18.查询各科成绩前三名的记录 select a.*,count(b.score)+1 as ranking from sc as a left join sc as b on a.cid=b.cid and a.score<b.score group by a.cid,a.sid having ranking <=3 order by a.cid,ranking --having where不能使用别名,group by order by中可以使用别名 -- select * from (select *,row_number()over(partition by cid order by score desc)as ranking from sc) where ranking>=3 ; 19.查询每门课程被选修的学生数 select cid,count(distinct sid) as num from sc group by cid ; 20.查询出只选修两门课程的学生学号和姓名 select sc.sid,student.sname from sc left join student on sc.sid=student.sid group by sc.cid having count(cid)=2 ; 21. 查询男生、女生人数 select count(case when ssex=‘男‘ then sid else null end)as ‘男生人数‘, count(case when ssex=‘女‘ then sid else null end)as ‘女生人数‘ from student ; 22. 查询名字中含有「风」字的学生信息 select * from student where sname like ‘%风%‘ ; 23查询同名同性学生名单,并统计同名人数 select sname,count(ssex) from student group by sname having count(ssex)>1 ; 24.查询 1990 年出生的学生名单 select * from student where year(sage) like‘1990%‘ ; 25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列 select cid,avg(score)as meanscore from sc group by cid order by meanscore desc,cid ; 26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩 select a.sid,student.sname,a.meanscore from (select sid,avg(score) as meanscore from sc group by sid having avg(score)>=85 )a left join student on a.sid=student.sid ; 27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数 select student.sname,b.socre from (select cid from course where cname =‘数学‘ )a left join (select * from sc where score<60 )b on a.cid=b.cid left join student on b.sid=student.sid ; 28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况) select sname,sc.cid,sc.score from sc join student on sc.sid=student.sid ; 29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数 select sname,sc.cid,sc.score from sc join student on sc.sid=student.sid where sc.score >70 ; 30.查询不及格的课程 select distinct cid from sc where score<60 ; 31.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名 select sc.sid,sname from (select * from sc where cid=‘01‘and score>80 )a left join student on a.sid=student.sid ; 32.求每门课程的学生人数 select cid, count(sid)as cnt from sc group by cid ; 33.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩 select student.*,sc.score from (select tid from teacher where tname=‘张三‘ )a left join course on a.tid=course.tid left join sc on course.cid=sc.cid left join student on sc.sid=student.sid order by sc.score desc limit 1 ; 34.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生 35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 select distinct a.* from sc as a join sc as b on a.score=b.score and a.cid!=b.cid ; 36. 查询每门成绩最好的前两名 select * from (select *, row_number()over(partition by cid order by score desc)as ranking ) where ranking <=2 ; --方法2自交 select * from sc where (select count(*) from sc as a where sc.cid=a.cid and sc.score<a.score )<2 order by cid ,sc.score desc ; 37. 统计每门课程的学生选修人数(超过 5 人的课程才统计) select cid,count(sid) from sc group by sc having count(sid)>5 ; 38.检索至少选修两门课程的学生学号 select cid,count(sid) from sc group by sc having count(sid)>2 ; 39.查询选修了全部课程的学生信息 select student.* from (select sid from sc where cid =(select count(distinct cid) from course ) )a left join student on a.sid=student.sid ; 40.查询各学生的年龄,只按年份来算 select sname,year(now())-year(age) as ‘年级‘ from student ; 41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一 select sname, case when (date_format(now(),‘%m-%d‘)-date_format(sage,‘%m-%d‘)<0 then year(now())-year(sage)+1 else year(now())-year(sage) end as ‘年龄‘ from student ; --date_format转化为时间戳,利用时间戳求差值 42.查询本周过生日的学生 select * from student where weekofyear(date_format(now(),‘%y%m%d‘)) = weekofyear(date_format(sage,‘%y%m%d‘)-date_format(sage,‘%y‘)*10000+date_format(now(),‘%y‘)*10000) ; --出生日期的年份去掉,得到月份和日期,再拼接上当前的年份 --weekofyear函数是计算出当前日期所在周数 43. 查询下周过生日的学生 select * from student where weekofyear(date_format(now(),‘%y%m%d‘))+1 = weekofyear(date_format(sage,‘%y%m%d‘)-date_format(sage,‘%y‘)*10000+date_format(now(),‘%y‘)*10000) ; 44.查询本月过生日的学生 select sname from student where month(sage)=month(now()) ; 45.查询下月过生日的学生 select sname from student where month(sage)=month(now())+1 ;
以上是关于SQL经典50题的主要内容,如果未能解决你的问题,请参考以下文章