练习题
与同学闲聊之余,知道了这一次的 MySQL 练习题,闲暇之余将前 18 道题完成了(按照作者的说法难度是依次递增的)
。我使用的是 MySQL 8.0.33,练习题中用到了一些 8.0 的新特性
查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数
1
2
3
4
5
6
7select t3.*, t1.score, t2.score
from sc t1
join sc t2 on t1.SId = t2.SId
join student t3 on t1.SId = t3.SId
where t1.CId = '01'
and t2.CId = '02'
and t1.score > t2.score;查询同时存在” 01 “课程和” 02 “课程的情况
1
2
3
4
5select *
from sc t1
join sc t2 on t1.SId = t2.SId
where t1.CId = '01'
and t2.CId = '02';查询存在” 01 “课程但可能不存在” 02 “课程的情况(不存在时显示为 null )
1
2
3
4select *
from sc t1
left join sc t2 on t1.SId = t2.SId and t2.CId = '02'
where t1.CId = '01';查询不存在” 01 “课程但存在” 02 “课程的情况
1
2
3
4
5
6select *
from sc
where sc.SId not in (select SId
from sc
where sc.CId = '01')
and sc.CId = '02';
查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
1
2
3
4
5select avg(t1.score), t1.SId, t2.Sname
from sc t1
join student t2 on t1.SId = t2.SId
group by t1.SId
having avg(t1.score) >= 60;查询在 SC 表存在成绩的学生信息
1
2
3
4select t2.*
from sc t1
join student t2 on t1.SId = t2.SId
group by t1.SId;查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
1
2
3
4select t1.SId, t1.Sname, count(t2.SId), sum(t2.score)
from student t1
left join sc t2 on t1.SId = t2.SId
group by t1.SId, t1.Sname;查有成绩的学生信息
1
2
3
4
5select t1.*
from student t1
left join sc t2 on t1.SId = t2.SId
where t2.SId is not null
group by t1.SId;
查询「李」姓老师的数量
1
2
3select count(1)
from teacher
where Tname like '李%';查询学过「张三」老师授课的同学的信息
1
2
3
4
5
6select t1.*
from student t1
join sc t2 on t1.SId = t2.SId
join course t3 on t2.CId = t3.CId
join teacher t4 on t3.TId = t4.TId and t4.Tname = '张三'
group by t2.SId;查询没有学全所有课程的同学的信息
1
2
3
4
5select t1.*, count(t2.sid)
from student t1
left join sc t2 on t1.SId = t2.SId
group by t1.SId
having count(t2.SId) < (select count(1) from course);查询至少有一门课与学号为” 01 “的同学所学相同的同学的信息
1
2
3
4
5select t3.*
from sc t2
join student t3 on t2.SId = t3.SId
where t2.cid in (select t1.CId from sc t1 where t1.SId = '01')
group by t3.SId;查询和” 01 “号的同学学习的课程 完全相同的其他同学的信息
1
2
3
4
5
6select group_concat(t1.CId order by t1.CId) as concat, t2.*
from sc t1
join student t2 on t1.SId = t2.SId
where t1.SId <> '01'
group by t1.SId
having concat = (select group_concat(CId order by CId) from sc where SId = '01');查询没学过”张三”老师讲授的任一门课程的学生姓名
1
2
3
4
5
6
7
8select *
from student
where SId not in (select t1.SId
from sc t1
join course t2 on t1.CId = t2.CId
join teacher t3 on t2.TId = t3.TId
where t3.Tname = '张三'
group by t1.SId);查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
1
2
3
4
5
6
7
8
9select t1.SId, t2.Sname, avg(t1.score)
from sc t1
join student t2 on t1.SId = t2.SId
where t1.SId in (select SId
from sc
where score < 60
group by SId
having count(SId) >= 2)
group by t1.SId;检索” 01 “课程分数小于 60,按分数降序排列的学生信息
1
2
3
4
5
6select t2.*, t1.score
from sc t1
join student t2 on t1.SId = t2.SId
where t1.CId = '01'
and t1.score < 60
order by t1.score desc;按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
1
2
3select t1.*, avg(t1.score) over (PARTITION BY t1.SId) as a
from sc t1
order by a desc;查询各科成绩最高分、最低分和平均分:
以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
1
2
3
4
5
6
7
8
9
10
11
12
13select t1.CId,
t2.Cname,
max(t1.score),
min(t1.score),
avg(t1.score),
sum(if(t1.score >= 60, 1, 0)) / count(*) as 及格率,
sum(if(t1.score >= 70 and t1.score < 80, 1, 0)) / count(*) as 中等率,
sum(if(t1.score >= 80 and t1.score < 90, 1, 0)) / count(*) as 优良率,
sum(if(t1.score >= 90, 1, 0)) / count(*) as 优秀率
from sc t1
join course t2 on t1.CId = t2.CId
group by t1.CId
order by count(*) desc, t1.CId;按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
1
2
3select CID, SID, score, rank() over (PARTITION BY CId order by score desc ) as rank1
from sc
order by CId, rank1;没看懂他的写法
1
2
3
4
5
6select a.cid, a.sid, a.score, count(b.score) + 1 as rank1
from sc as a
left join sc as b
on a.score < b.score and a.cid = b.cid
group by a.cid, a.sid, a.score
order by a.cid, rank1;按各科成绩进行排序,并显示排名, Score 重复时合并名次
1
2
3select CID, SID, score, dense_rank() over (PARTITION BY CId order by score desc ) as rank1
from sc
order by CId, rank1;
查询学生的总成绩,并进行排名,总分重复时保留名次空缺
1
2
3select SID, sum(score), rank() over (order by sum(score) desc)
from sc
group by SId;查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
1
2
3select SID, sum(score), dense_rank() over (order by sum(score) desc)
from sc
group by SId;
统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
1
2
3
4
5
6
7
8
9
10select t1.CId,
t2.Cname,
sum(if(t1.score <= 100 and t1.score > 85, 1, 0)) as '100-85',
sum(if(t1.score <= 85 and t1.score > 70, 1, 0)) as '85-70',
sum(if(t1.score <= 70 and t1.score > 60, 1, 0)) as '70-60',
sum(if(t1.score <= 60 and t1.score > 0, 1, 0)) as '60-0',
count(1)
from sc t1
join course t2 on t1.CId = t2.CId
group by t1.CId, t2.Cname;查询各科成绩前三名的记录
1
2
3
4
5with a as (select SId, CId, score, rank() over (PARTITION BY CId order by score desc ) as rank1
from sc)
select *
from a
where a.rank1 <= 3;
SQL 日期区间查询
日期范围获取每天(截止结束日期)
1
2
3SELECT DATE_ADD('2021-04-04', INTERVAL CAST(help_topic_id AS signed INTEGER) DAY) AS `date`
FROM mysql.help_topic
WHERE help_topic_id < DATEDIFF('2021-07-04', '2021-04-04') + 1;日期范围获取每月(截止结束日期所在月)
1
2
3SELECT DATE_FORMAT(DATE_ADD('2021-04-04', INTERVAL CAST(help_topic_id AS signed INTEGER) MONTH), '%Y-%m') AS `month`
FROM mysql.help_topic
WHERE help_topic_id < TIMESTAMPDIFF(MONTH, '2021-04-04', '2021-07-04') + 1;本周每天(截止今日)
1
2
3
4
5SELECT DATE_FORMAT(
DATE_ADD(DATE_SUB(NOW(), INTERVAL WEEKDAY(NOW()) + 0 DAY), INTERVAL CAST(help_topic_id AS signed INTEGER)
DAY), '%Y-%m-%d') AS `date`
FROM mysql.help_topic
WHERE help_topic_id <= WEEKDAY(NOW());近7日每天(截止今日)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(DATE_ADD(NOW(), INTERVAL - 6 DAY), INTERVAL CAST(help_topic_id AS SIGNED INTEGER) DAY),
'%Y-%m-%d') AS `date`
FROM mysql.help_topic
WHERE help_topic_id < 7;本月每天(截止今日)
1
2
3
4SELECT DATE_ADD(DATE_ADD(NOW(), INTERVAL - DAY(NOW()) + 1 DAY), INTERVAL CAST(help_topic_id AS signed INTEGER)
DAY) AS `date`
FROM mysql.help_topic
WHERE help_topic_id < DAY(NOW());近30日每天(截止今日)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(DATE_ADD(NOW(), INTERVAL - 29 DAY), INTERVAL CAST(help_topic_id AS SIGNED INTEGER) DAY),
'%Y-%m-%d') AS `date`
FROM mysql.help_topic
WHERE help_topic_id < 30;本季度每月(截止所在月)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(CONCAT(YEAR(NOW()), '-0', ((QUARTER(NOW()) - 1) * 3 + 1), '-01'), INTERVAL
CAST(help_topic_id AS SIGNED INTEGER) MONTH), '%Y-%m') as `month`
FROM mysql.help_topic
WHERE help_topic_id < MONTH(NOW()) % 3;近半年每月(截止所在月)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(DATE_ADD(NOW(), INTERVAL - 5 MONTH), INTERVAL CAST(help_topic_id AS SIGNED INTEGER) MONTH),
'%Y-%m') as `month`
FROM mysql.help_topic
WHERE help_topic_id < 6;本年每月(截止所在月)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(CONCAT(YEAR(NOW()), '-01-01'), INTERVAL CAST(help_topic_id AS SIGNED INTEGER) MONTH),
'%Y-%m') as `month`
FROM mysql.help_topic
WHERE help_topic_id < MONTH(NOW());近1年每月(截止所在月)
1
2
3
4SELECT DATE_FORMAT(DATE_ADD(DATE_ADD(NOW(), INTERVAL - 11 MONTH), INTERVAL CAST(help_topic_id AS SIGNED INTEGER) MONTH),
'%Y-%m') as `month`
FROM mysql.help_topic
WHERE help_topic_id < 12;