MYSQL45道练习题
表:Student
表:SC
表:Course
表:Teacher
1.查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
1 select a.sid,c.Sname,c.Sage,c.Ssex,a.score_01,b.score_02 2 from 3 -- 选出课程号为01的学生及成绩信息 4 (select SId,score as score_01 5 from SC 6 where CId='01') as a 7 INNER JOIN 8 -- 选出课程号为02的学生及成绩信息 9 (select SId,score as score_02 10 from SC 11 where CId='02') as b 12 on a.SId=b.SId 13 INNER JOIN Student as c 14 ON a.SId=c.SId 15 where a.score_01 > b.score_02
-1.1 查询同时存在" 01 "课程和" 02 "课程的情况
1 select a.sid,c.Sname,c.Sage,c.Ssex,a.score_01,b.score_02 2 from 3 -- 选出课程号为01的学生及成绩信息 4 (select SId,score as score_01 5 from SC 6 where CId='01') as a 7 INNER JOIN 8 -- 选出课程号为02的学生及成绩信息 9 (select SId,score as score_02 10 from SC 11 where CId='02') as b 12 on a.SId=b.SId 13 INNER JOIN Student as c 14 ON a.SId=c.SId
-1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
1 select a.sid,c.Sname,c.Sage,c.Ssex,a.score_01,b.score_02 2 from 3 -- 选出课程号为01的学生及成绩信息 4 (select SId,score as score_01 5 from SC 6 where CId='01') as a 7 LEFT JOIN 8 -- 选出课程号为02的学生及成绩信息 9 (select SId,score as score_02 10 from SC 11 where CId='02') as b 12 on a.SId=b.SId 13 INNER JOIN Student as c 14 ON a.SId=c.SId
-1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
1 select * 2 from SC as a 3 where SId not in (select SId from SC where CId='01') 4 and CId='02'
2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
1 select a.sid,b.sname,avg(score) as avg_score 2 from SC as a 3 INNER JOIN Student as b 4 on a.SId=b.SId 5 group by a.SId,b.Sname
3.查询在 SC 表存在成绩的学生信息
1 select * 2 from Student 3 where SId in (select DISTINCT SId from SC)
4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
1 select a.SId,a.Sname,count(b.CId),sum(b.score) 2 from Student as a 3 LEFT JOIN SC as b 4 on a.SId=b.SId 5 GROUP BY a.SId,a.Sname
5.查询「李」姓老师的数量
1 select count(*) 2 from Teacher 3 where Tname LIKE '李%'
6.查询学过「张三」老师授课的同学的信息
1 select * 2 from Student 3 where sid in(select sid 4 from SC 5 where cid in(select cid 6 from Course 7 where tid in(select TId 8 from Teacher 9 where tname='张三')))
7.查询没有学全所有课程的同学的信息
1 select a.SId,a.Sname,a.Sage,a.Ssex,count(b.CId) 2 from Student as a 3 LEFT JOIN SC as b on a.SId=b.SId 4 group by a.SId,a.Sname,a.Sage,a.Ssex 5 having count(b.CId)<(select count(CId) from Course)
8.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
1 select * 2 from Student as a 3 INNER JOIN (select distinct sid 4 from SC 5 where cid in (select cid 6 from SC 7 where sid='01')) as b 8 on a.SId=b.SId 9 -- inner join处理效率比where in高
9.查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
1 select * 2 from Student 3 -- 选出和01同学选课数量相同的同学 4 WHERE SId in (select SId 5 from SC 6 group by SId having count(CId)=(select count(CId) 7 from SC 8 where SId='01')) 9 -- 排除选了01同学所选课程以外课程的同学 10 and SId not in(select DISTINCT SId 11 from SC 12 where CId not in (SELECT CId 13 FROM SC 14 where SId='01'))
10.查询没学过"张三"老师讲授的任一门课程的学生姓名
1 select Sname 2 from Student 3 where sid not in(select sid 4 from SC 5 where cid in(select cid 6 from Course 7 where tid in(select TId 8 from Teacher 9 where tname='张三')))
11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
1 select a.SId,a.Sname,avg(score) 2 from Student as a 3 right join SC as b 4 on a.SId=b.SId 5 group by a.SId,a.Sname having a.sid in(select SId 6 from SC 7 where SC.score<60 8 group by SId having count(SId)>=2)
12.检索" 01 "课程分数小于 60,按分数降序排列的学生信息
1 select * 2 from SC as a 3 left join Student as b 4 on a.SId=b.SId 5 where a.CId='01' and a.score<60 6 order by a.score DESC
13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
1 select c.SId,a.CId,a.score,b.avg_score 2 from SC as a 3 left join (select SId,avg(score) as avg_score 4 from SC 5 group by SId) as b 6 on a.SId=b.SId 7 right join Student as c 8 on a.SId=c.SId 9 order by b.avg_score desc
14.查询各科成绩最高分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
1 -- 用if函数来做 2 select a.CId as '课程ID', 3 b.Cname as '课程name', 4 max(a.score) as '最高分', 5 min(a.score) as '最低分', 6 avg(a.score) as '平均分', 7 sum(if(a.score>=60,1,0))/count(a.score) as '及格率', 8 sum(if(a.score>=70 and a.score<=80,1,0))/count(a.score) as '中等率', 9 sum(if(a.score>=80 and a.score<=90,1,0))/count(a.score) as '优良率', 10 sum(if(a.score>=90,1,0))/count(a.score) as '优秀率' 11 from SC as a 12 join Course as b on a.CId=b.CId 13 group by a.CId,b.Cname 14 15 -- 用case when来做 16 select a.CId as '课程ID', 17 b.Cname as '课程name', 18 max(a.score) as '最高分', 19 min(a.score) as '最低分', 20 avg(a.score) as '平均分', 21 sum(case when a.score>=60 then 1 else 0 end)/count(a.score) as '及格率', 22 sum(case when a.score>=70 and a.score<=80 then 1 else 0 end)/count(a.score) as '中等率', 23 sum(case when a.score>=80 and a.score<=90 then 1 else 0 end)/count(a.score) as '优良率', 24 sum(case when a.score>=90 then 1 else 0 end)/count(a.score) as '优秀率' 25 from SC as a 26 join Course as b on a.CId=b.CId 27 group by a.CId,b.Cname
15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
1 -- @rank:=是赋值函数 2 select SId,CId,score,@rank:=@rank+1 as rn 3 from SC,(select @rank:=0) as t 4 order by score desc
1 -- 窗口函数row_number()可以对数据进行排序 2 select *, 3 row_number() over(order by score desc) as 'rank' 4 from sc
15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
1 -- 加入@sco判断本行分数与上一行是否相同 2 -- 保留@sco的写法 3 select SId, 4 CId, 5 score, 6 case when @sco=score then @rank else @rank:=@rank+1 end as rn, 7 @sco:=score 8 from SC,(select @rank:=0,@sco:=null) as t 9 order by score desc 10 11 -- 隐藏@sco的写法 12 select SId, 13 CId, 14 score, 15 case when @sco=score then @rank 16 when @sco:=score then @rank:=@rank+1 17 end as rn 18 from SC,(select @rank:=0,@sco:=null) as t 19 order by score desc
1 -- 窗口函数rank,可以对相同的分数输出同样的排名,总名次不变,排名是跳跃的 2 select *, 3 rank() over(order by score desc) as 'rank' 4 from sc
16.查询学生的总成绩,并进行排名,总分重复时保留名次空缺
1 -- 保留@sco的写法 2 select s.*, 3 @rank:=if(@sco=s_sco,'',@rank+1) as rn, 4 @sco:=s_sco 5 from (select SId, 6 sum(score) as s_sco 7 from SC 8 group by SId 9 order by s_sco desc) as s, 10 (select @rank:=0,@sco:=null) as t 11 12 -- 隐藏@sco的写法 13 select s.*, 14 case when @sco=s_sco then '' 15 when @sco:=s_sco then @rank:=@rank+1 end as rn 16 from (select SId, 17 sum(score) as s_sco 18 from SC 19 group by SId 20 order by s_sco desc) as s, 21 (select @rank:=0,@sco:=null) as t
16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
1 -- 保留@sco的写法 2 select s.*, 3 @rank:=if(@sco=s_sco,@rank,@rank+1) as rn, 4 @sco:=s_sco 5 from (select SId, 6 sum(score) as s_sco 7 from SC 8 group by SId 9 order by s_sco desc) as s, 10 (select @rank:=0,@sco:=null) as t 11 12 -- 隐藏@sco的写法 13 select s.*, 14 case when @sco=s_sco then @rank 15 when @sco:=s_sco then @rank:=@rank+1 end as rn 16 from (select SId, 17 sum(score) as s_sco 18 from SC 19 group by SId 20 order by s_sco desc) as s, 21 (select @rank:=0,@sco:=null) as t
1 -- 窗口函数方法一 2 select *,rank() over(order by s_sco desc) as 'rank' 3 from (select SId, 4 sum(score) as s_sco 5 from SC 6 group by SId) a 7 8 -- 窗口函数方法二 9 select SId, 10 sum(score) as s_sco, 11 rank() over(order by sum(score) desc) as 'rank' 12 from SC 13 group by SId
17.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
1 select c.Cname,s.* 2 from (select CId, 3 concat(sum(case when score<=60 and score>=0 then 1 else 0 end)/count(1)*100,'%') as '[0-60]', 4 concat(sum(case when score<=70 and score>60 then 1 else 0 end)/count(1)*100,'%') as '[60-70]', 5 concat(sum(case when score<=85 and score>70 then 1 else 0 end)/count(1)*100,'%') as '[70-85]', 6 concat(sum(case when score<=100 and score>85 then 1 else 0 end)/count(1)*100,'%') as '[85-100]' 7 from SC 8 group by CId) as s 9 inner join Course as c on s.CId=c.CId
18.查询各科成绩前三名的记录
1 select * 2 from sc as a 3 where (select count(1) from sc b where a.Cid=b.Cid and b.score>a.score)<3 4 order by cid asc,score desc
1 -- 窗口函数中的partition by用于定义分组排序的分组 2 select * 3 from 4 (select *,rank() over(partition by cid order by score desc) as rank_number 5 from sc) as a 6 where rank_number in (1,2,3) 7 order by cid asc,score desc
19.查询每门课程被选修的学生数
1 select cid,count(cid) 2 from sc 3 group by cid
20.查询出只选修两门课程的学生学号和姓名
1 select a.sid,a.sname 2 from student as a 3 join sc as b on a.sid=b.sid 4 group by a.sid,a.sname having count(b.cid)=2
21.查询男生、女生人数
1 select ssex,count(sid) 2 from student 3 group by ssex
22.查询名字中含有「风」字的学生信息
1 select * 2 from student 3 where sname like '%风%'
23.查询同名同性学生名单,并统计同名人数
1 select a.sname,a.ssex,count(a.sname) 2 from student as a 3 join student as b on a.sname=b.sname and a.ssex=b.ssex and a.sid!=b.sid 4 group by a.sname,a.ssex
24.查询 1990 年出生的学生名单
1 select * 2 from student 3 where year(sage)=1990
25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
1 select cid, 2 avg(score) as avg_sco 3 from sc 4 group by cid 5 order by avg_sco desc,cid asc;
26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
1 select a.sid,a.sname,b.avg_sco 2 from student as a 3 join (select sid, 4 avg(score) as avg_sco 5 from sc 6 group by sid having avg_sco>=85) as b 7 on a.sid=b.sid
27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
1 select a.sname,b.score 2 from student as a 3 join (select sid,score 4 from sc 5 where score<60 and cid=(select cid 6 from course 7 where cname='数学')) as b 8 on a.sid=b.sid
28.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
1 select a.*,b.cid,b.score 2 from student as a 3 left join sc as b on a.sid=b.sid
29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
1 select a.sname,b.cid,b.score 2 from student as a 3 right join sc as b on a.sid=b.sid 4 where b.score>70
30.查询不及格的课程
1 select distinct cid 2 from sc 3 where score<60
31.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
1 select sid,sname 2 from student 3 where sid in (select sid 4 from sc 5 where cid='01' and score>=80)
32.求每门课程的学生人数
1 select cid,count(sid) 2 from sc 3 group by cid
33.假设成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
1 select a.*,b.score 2 from student as a 3 join (select sid,score 4 from sc 5 where cid in (select cid 6 from course 7 where tid in (select tid 8 from teacher 9 where tname='张三'))) as b 10 on a.sid=b.sid 11 order by score desc 12 limit 1
34.假设成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
1 select * 2 from (select a.*,b.score,rank() over(order by b.score desc) as rank_number 3 from student as a 4 join (select sid,score 5 from sc 6 where cid in (select cid 7 from course 8 where tid in (select tid 9 from teacher 10 where tname='张三'))) as b 11 on a.sid=b.sid) as a 12 where rank_number=1
35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
1 select distinct a.* 2 from sc as a 3 join sc as b 4 on a.sid=b.sid and a.score=b.score and a.cid!=b.cid
36.查询每门功成绩最好的前两名
1 select * 2 from (select *,row_number() over(partition by cid order by score desc) as row_num 3 from sc) as a 4 where row_num in (1,2)
37.统计每门课程的学生选修人数(超过 5 人的课程才统计)
1 select cid,count(sid) 2 from sc 3 group by cid having count(sid)>5
38.检索至少选修两门课程的学生学号
1 select sid,count(cid) 2 from sc 3 group by sid having count(cid)>=2
39.查询选修了全部课程的学生信息
1 select sid,count(cid) 2 from sc 3 group by sid having count(cid)=(select count(cid) 4 from course)
40.查询各学生的年龄,只按年份来算
1 select *,year(now())-year(sage) as age 2 from student
41.按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
1 select *,timestampdiff(year,sage,now()) as age 2 from student
42.查询本周过生日的学生
1 select * 2 from student 3 where week(concat('2020-',substr(sage,6,5)))=week(now())
43.查询下周过生日的学生
select * from student where week(concat('2020-',substr(sage,6,5)))=week(now())+1
44.查询本月过生日的学生
1 select * 2 from student 3 where month(sage)=month(now())
45.查询下月过生日的学生
1 select * 2 from student 3 where month(sage)=month(now())+1