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

 

posted @ 2020-08-16 17:15  醴酒微甜  阅读(431)  评论(0编辑  收藏  举报