习题来源于网络,sql语句是自己的答案,部分有参考。欢迎指正及探讨。
测试用数据表
1. 学生表 Student
--SId 学生编号, Sname 学生姓名, Sage 出生年月, Ssex 学生性别
create table Student (SId varchar(10), Sname varchar(10), Sage datetime, Ssex varchar(10));
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-12-20' , '男');
insert into Student values('04' , '李云' , '1990-12-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-01-01' , '女');
insert into Student values('07' , '郑竹' , '1989-01-01' , '女');
insert into Student values('09' , '张三' , '2017-12-20' , '女');
insert into Student values('10' , '李四' , '2017-12-25' , '女');
insert into Student values('11' , '李四' , '2012-06-06' , '女');
insert into Student values('12' , '赵六' , '2013-06-13' , '女');
insert into Student values('13' , '孙七' , '2014-06-01' , '女');
2. 课程表 Course
--CId 课程编号, Cname 课程名称, TId 教师编号
create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10))
insert into Course values('01' , '语文' , '02')
insert into Course values('02' , '数学' , '01')
insert into Course values('03' , '英语' , '03')
3. 教师表 Teacher
--TId 教师编号, Tname 教师姓名
create table Teacher(TId varchar(10),Tname varchar(10))
insert into Teacher values('01' , '张三')
insert into Teacher values('02' , '李四')
insert into Teacher values('03' , '王五')
4. 成绩表 SC
--SId 学生编号, CId 课程编号, score 分数
create table SC(SId varchar(10),CId varchar(10),score decimal(18,1))
insert into SC values('01' , '01' , 80)
insert into SC values('01' , '02' , 90)
insert into SC values('01' , '03' , 99)
insert into SC values('02' , '01' , 70)
insert into SC values('02' , '02' , 60)
insert into SC values('02' , '03' , 80)
insert into SC values('03' , '01' , 80)
insert into SC values('03' , '02' , 80)
insert into SC values('03' , '03' , 80)
insert into SC values('04' , '01' , 50)
insert into SC values('04' , '02' , 30)
insert into SC values('04' , '03' , 20)
insert into SC values('05' , '01' , 76)
insert into SC values('05' , '02' , 87)
insert into SC values('06' , '01' , 31)
insert into SC values('06' , '03' , 34)
insert into SC values('07' , '02' , 89)
insert into SC values('07' , '03' , 98)
习题及答案 无答案版在最下方
1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
-- 1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
select
Student.*
from
(select a.Sid
from (select * from SC where Cid = '01') a
join (select * from SC where Cid = '02') b
on a.Sid = b.Sid
and a.score > b.score) r
left join Student
on r.Sid = Student.Sid;
1.1 查询同时存在" 01 "课程和" 02 "课程的情况
-- 1.1 查询同时存在" 01 "课程和" 02 "课程的情况
--解法一
select * from SC
where Sid in (
select Sid from SC
where Sid in (select Sid from SC where Cid = '01')
and Cid = '02');
--解法二
select *
from (select * from SC where Cid = '02') a
join (select * from SC where Cid = '01') b
on a.Sid = b.Sid;
1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null)
null提示:使用left join
-- 1.2查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null)
select *
from (select * from SC where Cid = '02') a
left join (select * from SC where Cid = '01') b
on a.Sid = b.Sid;
1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
-- 1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
select * from SC
where Sid not in (select Sid from SC where Cid = '01')
and Cid = '02';
2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
-- 2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
select Student.* , a.avg_score
from Student,
(select Sid, avg(score) as avg_score from SC group by Sid having avg(score) >= 60) as a
where Student.Sid = a.Sid;
3. 查询在 SC 表存在成绩的学生信息
-- 3. 查询在 SC 表存在成绩的学生信息
select Student.* from Student
where Sid in (select distinct Sid from SC);
4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null)
-- 4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null)
select
Student.Sid,
Student.Sname,
a.*
from Student
left join (select Sid, count(Cid) as '选课总数', sum(score) as '总成绩' from SC group by Sid) as a
on Student.Sid = a.Sid;
4.1 查有成绩的学生信息
-- 4.1 查有成绩的学生信息
select * from Student
where Sid in (select distinct Sid from SC);
5. 查询「李」姓老师的数量
-- 5. 查询「李」姓老师的数量
select count(Tname) as '李姓教师数量' from Teacher where Tname like '李%';
6. 查询学过「张三」老师授课的同学的信息
-- 6 查询学过「张三」老师授课的同学的信息
select Student.* from Student where Sid in (
select Sid from SC, Course, Teacher
where Teacher.Tname = '张三'
and Teacher.Tid = Course.Tid
and Course.Cid = SC.Cid);
7. 查询没有学全所有课程的同学的信息
-- 7. 查询没有学全所有课程的同学的信息
select Student.* from Student
where Sid not in
(select Sid from
(select Sid, count(distinct Cid) as s_course_cnt from SC group by Sid) a,
(select count(distinct Cid) as tot_course_cnt from Course) b
where a.s_course_cnt = b.tot_course_cnt);
8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
-- 8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
select Student.* from Student where Sid in
(select Sid from SC where Cid in
(select Cid from SC where Sid = '01') and Sid <> '01');
9. 查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
-- 9. 查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
select Student.* from Student
where Sid in (
select Sid, count(distinct Cid) as s_course_cnt
from SC group by Sid
having count(Cid) = (select count(Cid) from SC where Sid = '01' )
and Sid not in (select Sid, Cid from SC where Cid not in (select Cid from SC where Sid = '01' ))));
10. 查询没学过"张三"老师讲授的任一门课程的学生姓名
-- 10. 查询没学过"张三"老师讲授的任一门课程的学生姓名
select Student.Sname from Student where Sid not in
(select Sid from SC, Course, Teacher
where Teacher.Tname like '张三'
and Teacher.Tid = Course.Tid
and Course.Cid = SC.Cid);
11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
-- 11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select Sid, Student.Sname, avg(score) as '平均成绩'
from SC, Student
where SC.Sid = Student.Sid
and Sid in (select Sid from SC where score < 60 group by Sid having count(score) >=2);
12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息
-- 12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息
select Student.*, Cid, score from Student, SC
where score < 60 and Cid = '01' and SC.Sid = Student.Sid
order by score desc;
13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
-- 13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select SC.*, avg_score
from SC left join (select Sid, avg(score) as avg_score from SC) a
on SC.Sid = a.Sid;
14. 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率(及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
-- 14. 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率(及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90)
select Cid, Course.Cname,
sum(case when score >= 90 then 1 else 0 end) * 100 / count(score) as '优秀率',
sum(case when score >= 80 and score < 90 then 1 else 0 end) * 100 / count(score) as '优良率',
sum(case when score >= 70 and score < 80 then 1 else 0 end) * 100 / count(score) as '中等率',
sum(case when score >= 60 then 1 else 0 end) * 100 / count(score) as '及格率',
max(score) as '最高分',
min(score) as '最低分',
avg(score) as '平均分'
from SC group by Cid;
14.1要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
-- 14.1 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select Cid, count(Sid) as '选修人数'
from SC group by Cid
order by count(Sid) desc;
15. 按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
-- 15. 按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
select a.cid, a.sid, a.score, count(b.score)+1 as rank
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, rank ASC;
15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
-- 15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
set @crank=0;
select q.Sid, q.Cid, q.score, @crank := @crank +1 as rank from(
select SC.Sid, SC.Cid, SC.score from SC
group by SC.Cid, SC.Sid
order by SC.Cid, SC.score desc)q;
16. 查询学生的总成绩,并进行排名,总分重复时保留名次空缺
-- 16. 查询学生的总成绩,并进行排名,总分重复时保留名次空缺
select a.Sid, a.tot_score, count(b.tot_score) + 1 as rank
from (select Sid, sum(score) as tot_score from SC group by Sid) a
left join (select Sid, sum(score) as tot_score from SC group by Sid) b
on a.tot_score < b.tot_score
group by a.Sid, a.tot_score
order by rank asc;
16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
-- 16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
set @crank=0;
select q.Sid, total, @crank := @crank +1 as rank from(
select SC.Sid, sum(SC.score) as total from SC
group by SC.Sid
order by total desc)q;
17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
-- 17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
select SC.Cid, Course.Cname, count(SC.Sid)
sum(case when score >= 85 then 1 else 0 end) * 100 / count(score) as '[100-85]',
sum(case when score >= 70 and score < 85 then 1 else 0 end) * 100 / count(score) as '[85-70]',
sum(case when score >= 60 and score < 70 then 1 else 0 end) * 100 / count(score) as '[70-60]',
sum(case when score >= 0 and score < 60 then 1 else 0 end) * 100 / count(score) as '[60-0]'
from SC, Course
where SC.Cid = Course.Cid
group by Cid;
18. 查询各科成绩前三名的记录
-- 18. 查询各科成绩前三名的记录
select a.Cid, a.Sid, a.score, count(b.score) + 1 from
(select * from SC group by Cid, Sid, score) a
left join (select * from SC group by Cid, Sid, score) b
on a.Cid = b.Cid and a.score < b.score
group by a.Cid, a.Sid, a.score having count(b.score) < 3
order by a.Cid asc, a.score desc;
19. 查询每门课程被选修的学生数
-- 19. 查询每门课程被选修的学生数
select Cid, count(score) as '选修学生数' from SC group by Cid;
20. 查询出只选修两门课程的学生学号和姓名
-- 20. 查询出只选修两门课程的学生学号和姓名
select a.Sid, Student.Sname
from (select Sid from SC group by Sid having count(Cid) = 2) a, Student
where a.Sid = Student.Sid;
21. 查询男生、女生人数
-- 21. 查询男生、女生人数
select Ssex, count(Sid) as '学生人数' from Student group by Ssex;
22. 查询名字中含有「风」字的学生信息
-- 22. 查询名字中含有「风」字的学生信息
select * from Student where Sname like '%风%';
23. 查询同名同性学生名单,并统计同名人数
-- 23. 查询同名同性学生名单,并统计同名人数
select Student.Sname, Student.Sid, a.stu_cnt as '学生人数'
from Student, (select Sname, count(Sid) as stu_cnt from Student group by Sname having count(Sid) > 1) a
where Student.Sname = a.Sname;
24. 查询 1990 年出生的学生名单
-- 24. 查询 1990 年出生的学生名单
select * from Student where year(Sage) = 1990;
25. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
-- 25. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select Cid, avg(score) from SC group by Cid order by Cid acs;
26. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
-- 26. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
select SC.Sid, Student.Sname, avg(score) from SC, Student where SC.Sid = Student.Sid group by SC.Sid having avg(score) >= 85;
27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
-- 27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
select SC.Sid, Student.Sname, SC.score from SC, Student where SC.Sid = Student.Sid and score < 60 and Cid = (select Cid from Course where Cname = '数学');
28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
-- 28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
select Student.Sid, Student.Sname, SC.Cid, SC.score from Student left join SC on SC.Sid = Student.Sid;
29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
-- 29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
select Student.Sid, Student.Sname, SC.Cid, SC.score from Student left join SC on SC.Sid = Student.Sid;
30. 查询不及格的课程
-- 30. 查询不及格的课程
select Cid from SC where score < 60;
31. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
-- 31. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
select Student.Sid, substring(Student.Sname,1,1) as '姓' from SC, Student where SC.Sid = Student.Sid and SC.score > 80 and SC.Cid = '01';
32. 求每门课程的学生人数
-- 32. 求每门课程的学生人数
select Cid, count(Sid) from SC group by Cid;
33. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
-- 33. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select Student.*, SC.score from Student, SC, Course, Teacher
where Student.Sid = SC.Sid and SC.Cid = Course.Cid and Course.Tid = Teacher.Tid and Teacher.Tname = '张三'
order by SC.score desc
limit 1;
34. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
-- 34. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select Student.*, SC.score from Student, SC where Student.Sid = SC.Sid
and score = (
select SC.score from SC, Course, Teacher
where SC.Cid = Course.Cid and Course.Tid = Teacher.Tid and Teacher.Tname = '张三'
order by SC.score desc
limit 1);
35. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
-- 35. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select Sid, Cid, score from SC where score in (select score from SC group by score having count(distinct Cid) > 1);
36. 查询每门功成绩最好的前两名
-- 36. 查询每门功成绩最好的前两名
select a.*, count(b.score) + 1 as rank
from SC a
left join SC b
on a.Cid = b.Cid and a.score < b.score
group by a.Cid, a.score, a.Sid
having count(b.score) < 2;
37. 统计每门课程的学生选修人数(超过 5 人的课程才统计)
-- 37. 统计每门课程的学生选修人数(超过 5 人的课程才统计)
select Cid, count(Sid) from SC group by Cid having count(Sid) > 5;
38. 检索至少选修两门课程的学生学号
-- 38. 检索至少选修两门课程的学生学号
select Sid from SC group by Sid having count(Cid) >=2;
39. 查询选修了全部课程的学生信息
-- 39. 查询选修了全部课程的学生信息
select Student.* from Student, SC where Student.Sid = SC.Sid group by SC.Sid having count(Cid) = (select count(Cid) from Course);
40. 查询各学生的年龄,只按年份来算
-- 40. 查询各学生的年龄,只按年份来算
select Sid, Sname, (year(CURDATE()) - year(Sage)) as age from Student;
41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
-- 41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
select Sid, Sname, timestampdiff(YEAR, Sage, CURDATE()) age from Student;
42. 查询本周过生日的学生
-- 42. 查询本周过生日的学生
select * from Student where weekofyear(Sage) = weekofyear(CURDATE());
43. 查询下周过生日的学生
-- 43. 查询下周过生日的学生
select * from Student where weekofyear(Sage) = weekofyear(CURDATE()) + 1;
44. 查询本月过生日的学生
-- 44. 查询本月过生日的学生
select * from Student where month(Sage) = month(CURDATE());
45. 查询下月过生日的学生
-- 45. 查询下月过生日的学生
select * from Student where month(Sage) = month(CURDATE()) + 1;
习题
- 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
1.1 查询同时存在" 01 "课程和" 02 "课程的情况
1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
-
查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
-
查询在 SC 表存在成绩的学生信息
-
查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
4.1 查有成绩的学生信息
-
查询「李」姓老师的数量
-
查询学过「张三」老师授课的同学的信息
-
查询没有学全所有课程的同学的信息
-
查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
-
查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
-
查询没学过"张三"老师讲授的任一门课程的学生姓名
-
查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
-
检索" 01 "课程分数小于 60,按分数降序排列的学生信息
-
按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
-
查询各科成绩最高分、最低分和平均分:以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率,及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
-
按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
- 查询学生的总成绩,并进行排名,总分重复时保留名次空缺
16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
-
统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
-
查询各科成绩前三名的记录
-
查询每门课程被选修的学生数
-
查询出只选修两门课程的学生学号和姓名
-
查询男生、女生人数
-
查询名字中含有「风」字的学生信息
-
查询同名同性学生名单,并统计同名人数
-
查询 1990 年出生的学生名单
-
查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
-
查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
-
查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
-
查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
-
查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
-
查询不及格的课程
-
查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
-
求每门课程的学生人数
-
成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
-
成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
-
查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
-
查询每门功成绩最好的前两名
-
统计每门课程的学生选修人数(超过 5 人的课程才统计)。
-
检索至少选修两门课程的学生学号
-
查询选修了全部课程的学生信息
-
查询各学生的年龄,只按年份来算
-
按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
-
查询本周过生日的学生
-
查询下周过生日的学生
-
查询本月过生日的学生
-
查询下月过生日的学生
网友评论