四、MYSQL数据练习题(一)

我的MYSQL版本是mysql-5.7.24-winx64,每天练习1道习题。

如果有错误或者更优的解决方法,欢迎大家指出,谢谢!!

一、测试表格

--1.学生表
Student(Sid,Sname,Sage,Ssex) 

--Sid 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别

 

CREATE TABLE `student` (
`Sid` varchar(20) DEFAULT NULL,
`Sname` varchar(20) DEFAULT NULL,
`Sage` datetime DEFAULT NULL,
`Ssex` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--2.课程表 
Course(Cid,Cname,Tno) 

--Cid --课程编号,Cname 课程名称,Tid教师编号

CREATE TABLE `course` (
`Cid` varchar(12) DEFAULT NULL,
`Cname` varchar(120) DEFAULT NULL,
`Tid` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

--3.教师表 
Teacher(Tid,Tname)

 --Tid 教师编号,Tname 教师姓名

CREATE TABLE `teacher` (
`Tid` varchar(12) DEFAULT NULL,
`Tname` varchar(120) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--4.成绩表 
SC(Sid,Cid,score)

 --Sid 学生编号,Cid 课程编号,score 分数

CREATE TABLE `sc` (
`Sid` varchar(12) DEFAULT NULL,
`Cid` varchar(20) DEFAULT NULL,
`score` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

二、插入测试数据

2.1 Student学生表

INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01 00:00:00', '');
INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21 00:00:00', '');
INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20 00:00:00', '');
INSERT INTO `student` VALUES ('04', '李云', '1990-08-06 00:00:00', '');
INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01 00:00:00', '');
INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01 00:00:00', '');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01 00:00:00', '');
INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20 00:00:00', '');

 

2.2 Course课程表

INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');

 

2.3 Teacher教师表

INSERT INTO `teacher` VALUES ('01', '张三');
INSERT INTO `teacher` VALUES ('02', '李四');
INSERT INTO `teacher` VALUES ('03', '王五');

 

2.4 SC成绩表

 

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 "课程成绩高的学生的信息及课程分数

-- 思路:分为4步:
-- 1、可以用两个sc表进行比较,一个表查询01课程的分数,然后另外一个表查询02课程的分数。
-- 2、将两表使用join on  进行联查,查询Sid相等的数据,就得到了这个学生同时有01、02课程的数据;
-- 3、 再根据步骤2查询01课程比02课程成绩高的数据。
-- 4、再结合studnet表查询出学生信息

-- 步骤1:select * from sc as A where A.Cid = '01';select * from sc as B where B.Cid = '02';
-- 步骤2、3:SELECT A.Sid,A.Cid,A.score from (select * from sc where Cid = '01') as A  JOIN (select * from sc  where Cid = '02') as B ON B.Sid = A.Sid WHERE A.score > B.score;
-- 步骤4:
select student.*,C.Cid,C.score from student JOIN (SELECT A.Sid,A.Cid,A.score from (select * from sc where Cid = '01') as A  JOIN (select * from sc  where Cid = '02') as B ON B.Sid = A.Sid WHERE A.score > B.score) as C on C.Sid = student.Sid;

1.1 查询同时存在" 01 "课程和" 02 "课程的情况

-- 思路:分为2步:
-- 1、可以用两个sc表进行比较,一个表查询01课程的分数,然后另外一个表查询02课程的分数。
-- 2、将两表使用join on  进行联查,查询Sid相等的数据,就得到了这个学生同时有01、02课程的数据;

-- 步骤1:select * from sc where Cid='01';select * from sc where Cid='02';
-- 步骤2:
select * from (select * from sc where Cid ='01' ) as A  JOIN (select * from sc where Cid ='02') as B on B.Sid = A.Sid;

1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )

-- 思路:分为2步:
-- 1、可以用两个sc表进行比较,一个表查询01课程的分数,然后另外一个表查询02课程的分数。
-- 2、将两表使用left join on  进行联查,查询Sid相等的数据,就得到了这个学生有01,但可能不存在02课程的数据;

-- 步骤1:select * from sc where Cid='01';select * from sc where Cid='02';
-- 步骤2:
select * from (select * from sc where Cid ='01' ) as A  left JOIN (select * from sc where Cid ='02') as B on B.Sid = A.Sid;

1.3 查询不存在" 01 "课程但存在" 02 "课程的情况

-- 思路:分为2步:
-- 1、可以用两个sc表进行比较,一个表查询不存在01课程的分数,然后另外一个表查询02课程的分数。
-- 2、将两表使用 join on  进行联查,查询Sid相等的数据,就得到了这个学生不存在01,但存在02课程的数据;

-- 步骤1:select * from sc where Cid='01';select * from sc where Cid='02';
-- 步骤2:
select * from (select * from sc where Cid !='01' ) as A   JOIN (select * from sc where Cid ='02') as B on B.Sid = A.Sid;

2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

-- 思路:分为两步,
-- 1、先根据Sid对sc表进行分类汇总,使用AVG函数和限定条件得到学生平均分;
-- 2、结合Student表,使用join on 得到学生姓名、编号和平均成绩。
-- 步骤1:select AVG(score) as '平均分' from sc GROUP BY Sid HAVING AVG(score)>=60;
-- 步骤2:
select student.Sid,Sname,A.`平均分` from student join (select Sid,AVG(score) as '平均分' from sc GROUP BY Sid HAVING AVG(score)>=60) as A on A.Sid = student.Sid;

3. 查询在 SC 表存在成绩的学生信息

-- 思路:
-- 1、先查询sc表的Sid,去重后作为限定条件,在student表中查询数据。
select * from student where Sid in (select DISTINCT Sid from sc);

4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )

-- 思路:
-- 1、在sc表中先查询选课总数、所有课程总成绩;
-- 2、结合student表、sc表根据Sid使用left join on 进行查询(因为没成绩的显示为null,所以是left)。

-- 步骤1:select Sid,COUNT(Cid),SUM(score) from sc GROUP BY Sid;
-- 步骤2:
select Sname,B.Sid,B.Totla1,B.Total2 from student LEFT JOIN (select Sid,COUNT(Cid) as Totla1,SUM(score) as Total2 from sc GROUP BY Sid) AS B ON B.Sid = student.Sid;

4.1 查有成绩的学生信息

-- 思路:
-- 1、在sc表中先查询选课总数、所有课程总成绩;
-- 2、结合student表、sc表根据Sid使用right join on 进行查询(因为没成绩的显示为null,所以是right)。

-- 步骤1:select Sid,COUNT(Cid),SUM(score) from sc GROUP BY Sid;
-- 步骤2:
select * from student RIGHT JOIN (select Sid,COUNT(Cid) as Totla1,SUM(score) as Total2 from sc GROUP BY Sid) AS B ON B.Sid = student.Sid;

5. 查询「李」姓老师的数量 

-- 思路:
-- 1、使用like方法和count函数在teacher表中查询即可;

-- 步骤1:
select count(*) from teacher where Tname like '李%';

 

6. 查询学过「张三」老师授课的同学的信息 

-- 思路:
-- 1、根据teacher表查询出张三的Tid;
select * from teacher where Tname = '张三' ;
-- 2、根据步骤1的Tid在Course表中查出Cid;
select * from course where Tid in (select Tid from teacher where Tname = '张三');
-- 3、根据步骤2的到的Cid作为限定条件,在sc表中查学生的Sid
select Sid from sc where Cid in (select Cid from course where Tid in (select Tid from teacher where Tname = '张三'));
-- 4、根据步骤3得到的Sid,在student表中查询出学生信息;
select * from student where Sid in (select Sid from sc where Cid in (select Cid from course where Tid in (select Tid from teacher where Tname = '张三')));

 

7. 查询没有学全所有课程的同学的信息 

-- 简单思路:涉及到的表课程表course、学生信息表student、通过成绩表sc来判断是否学全所有课程的学生。
-- 思路描述:先统计课程表course的总课程数,然后在成绩表sc中统计各个学生的课程数,找到与课程表course的总课程数不相等的Sid(这里要考虑到1门都没有的情况),然后根据Sid在学生信息表student中查询学生信息。
-- 1、统计课程表course的总课程数;
select COUNT(Cid)  FROM course;
-- 2、统计成绩表sc中统计各个学生的课程数;
select Sid,COUNT(Cid) FROM sc GROUP BY Sid;
-- 3、以步骤1的查询结果作为限定条件,查询与课程表course的总课程数不相等的Sid
select Sid,COUNT(Cid)as TotalCourse FROM sc GROUP BY Sid HAVING TotalCourse  not in (select COUNT(Cid) as S FROM course); 
-- 4、根据步骤3查询出来的Sid结合student表查询学生信息;
select * from student where Sid in (select Sid from (select Sid,COUNT(Cid)as TotalCourse FROM sc GROUP BY Sid HAVING TotalCourse  not in (select COUNT(Cid) as S FROM course))As A);
-- 5、结合sc表和student表确定没有成绩的同学的信息;
select * from student WHERE Sid not in (select Sid FROM sc GROUP BY Sid);
-- 使用union连接4、5查出结果
select * from student where Sid in (select Sid from (select Sid,COUNT(Cid)as TotalCourse FROM sc GROUP BY Sid HAVING TotalCourse  not in (select COUNT(Cid) as S FROM course))As A) UNION select * from student WHERE Sid not in (select Sid FROM sc GROUP BY Sid);
 

 

8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息 

-- 简单思路:涉及到的表课程表course、学生信息表student、通过成绩表sc来判断是否所学相同。
-- 思路描述:
-- 1、在成绩表sc中查询学号为01的学生Cid;
select Cid from sc where Sid = '01';
-- 2、将步骤1的结果作为限定条件再在sc表中使用 IN 查询Cid在步骤1的结果中的学生的Sid;
SELECT DISTINCT Sid from sc where Cid in (select Cid from sc where Sid = '01');
-- 在学生信息表student中根据步骤2的查询结果作为限定条件查询学生信息。
select * from student where Sid in (SELECT DISTINCT Sid from sc where Cid in (select Cid from sc where Sid = '01'));

 

9. 查询和" 01 "号的同学学习的课程完全相同的其他同学的信息 

-- 涉及到的表:成绩表sc,学生信息表student
-- 思路:要查询和01学号同学学习完全相同的课程,统计sc表中各个学生的课程总数,和01学生相同的学生的Sid,然后根据查询到的Sid在student表中查询即可。

-- 步骤1:查询01号学生的课程总数
select COUNT(Cid) from sc where Sid='01';
-- 步骤2:查询和01号学生的课程总数相同的其他学生的Sid;
select Sid from sc GROUP BY Sid HAVING Sid!='01' and COUNT(Cid) = (select COUNT(Cid) from sc where Sid='01');
-- 步骤3:根据步骤2得到的Sid,在student表中查询学生信息
select * from student where Sid in (select Sid from sc GROUP BY Sid HAVING Sid!='01' and COUNT(Cid) = (select COUNT(Cid) from sc where Sid='01'));

10. 查询没学过"张三"老师讲授的任一门课程的学生姓名 

-- 10. 查询没学过"张三"老师讲授的任一门课程的学生姓名 
-- 涉及到的表:老师表teacher,课程表course,成绩表sc,学生信息表student
-- 思路:通过老师姓名在老师表teacher中查询课程号Tid,在课程表course中根据Tid查询Cid,然后在成绩表sc中根据Cid,查询没有学过老师课程的学生Sid,再根据查询到的Sid在学生信息表中查询学生姓名。
-- 步骤1:通过老师姓名在老师表teacher中查询课程号Tid;
select Tid from teacher where Tname ='张三';
-- 步骤2:在课程表course中根据Tid查询Cid;
select Cid from course WHERE Tid in (select Tid from teacher where Tname ='张三');
-- 步骤3:通过查询到的课程号Cid,在成绩表sc中查询没有学过老师课程的学生Sid;
select DISTINCT Sid from sc where Cid not in (select Cid from course WHERE Tid in (select Tid from teacher where Tname ='张三'));
-- 步骤4:查询到的Sid在学生信息表student中查询学生姓名.
SELECT * from student where Sid in (select DISTINCT Sid from sc where Cid not in (select Cid from course WHERE Tid in (select Tid from teacher where Tname ='张三')));

11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 

-- 10. 11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩  
-- 涉及到的表:成绩表sc,学生信息表student
-- 思路:在成绩表sc中先查出成绩不合格的学生信息,然后按照Sid分组统计次数大于等于2次的学生的Sid。再根据查询到的Sid在学生信息表student中查询学生的姓名。
-- 步骤1:在成绩表sc中先查出成绩不合格的学生信息;
select * from sc where score <60;
-- 步骤2:按照Sid分组统计次数大于等于2次的学生的Sid;
select A.Sid from (select  Sid from sc where score <60) as A GROUP BY A.Sid  HAVING COUNT(A.Sid)>=2 ;
-- 步骤3:根据查询到的Sid在学生信息表student中查询学生的姓名。
select student.Sid,Sname from student JOIN (select A.Sid from (select * from sc where score <60) as A GROUP BY A.Sid  HAVING COUNT(A.Sid)>=2) AS B on B.Sid = student.Sid;
-- 步骤4:根据前面查询到的Sid,在成绩表sc中查询这些学生的平均成绩;
SELECT sc.Sid,AVG(score) FROM sc join (select A.Sid from (select * from sc where score <60) as A GROUP BY A.Sid  HAVING COUNT(A.Sid)>=2 ) AS C on C.Sid = sc.Sid GROUP BY Sid;
-- 步骤5:信息拼接,将平均分拼接到步骤3中
select E.*,F.avgscore from (select student.Sid,Sname from student JOIN (select A.Sid from (select * from sc where score <60) as A GROUP BY A.Sid  HAVING COUNT(A.Sid)>=2) AS B on B.Sid = student.Sid)  as E JOIN (SELECT sc.Sid,AVG(score) as avgscore FROM sc join (select A.Sid from (select * from sc where score <60) as A GROUP BY A.Sid  HAVING COUNT(A.Sid)>=2 ) AS C on C.Sid = sc.Sid GROUP BY Sid) as F on F.Sid = E.Sid;

12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息

-- 12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息
-- 涉及到的表:成绩表sc,学生信息表student
-- 思路:先在sc表中根据课程号检索出‘01’课程的信息,然后去除60分及以上的信息,在进行降序。然后根据查询出的信息中的Sid,结合student表查询学生信息。
-- 步骤1:先在sc表中根据课程号检索出‘01’课程的信息;
select Sid from sc where Cid= '01' and score < 60 ORDER BY score DESC;

-- 步骤2:根据查询出的信息中的Sid,结合student表查询学生信息。
select student.Sid,Sname,Sage        from student JOIN (select Sid from sc where Cid= '01' and score < 60 ORDER BY score DESC) AS A on A.Sid = student.Sid;
;

13. 查询每门课程被选修的学生数 

-- 求每门课程的学生人数
-- 思路:根据课程号分组统计
select Cid,COUNT(Sid) from sc GROUP BY Cid;

14. 查询出只选修两门课程的学生学号和姓名

-- 查询出只选修两门课程的学生学号和姓名 
-- 思路:在成绩表sc中查询只选修两门课程的学生Sid,再根据Sid在学生信息表中进行查询。
-- 步骤1:成绩表sc中查询只选修两门课程的学生Sid(根据Sid出现的次数进行统计)
select Sid from sc GROUP BY Sid HAVING COUNT(Sid)=2;

-- 步骤2:将获取到的Sid在student表中查询。
select * from student where Sid in (select Sid from sc GROUP BY Sid HAVING COUNT(Sid)=2);

15. 查询男生、女生人数

-- 查询男生、女生人数
-- 思路:在学生信息表student中根据性别统计
select Ssex,COUNT(Sid) from student GROUP BY Ssex;

16. 查询名字中含有「风」字的学生信息

-- 查询名字中含有「风」字的学生信息
-- 思路:在学生信息表student中使用模糊查询
select * from student where Sname like '%风%';

17. 查询同名同性学生名单,并统计同名人数

-- 查询同名同性学生名单,并统计同名人数
-- 思路:在学生信息表student中根据姓名进行分组,统计出现2次及以上的学生姓名。

-- 步骤1:学生信息表student中根据姓名进行分组,查询同名学生。
select * from student GROUP BY Sname HAVING COUNT(Sname)>1;

-- 步骤2:根据查询到的学生姓名在student表中查询这些学生姓名的学生信息。
select * from student  where Sname in (select Sname from student GROUP BY Sname HAVING COUNT(Sname)>1) ;

-- 根据性别和姓名进行分组,将姓名和性别相同的分到一组,姓名性别相同的即位同名同姓;
select *,COUNT(A.Ssex) as '同名人数' from (select * from student  where Sname in (select Sname from student GROUP BY Sname HAVING COUNT(Sname)>1))as A GROUP BY A.Ssex,A.Sname HAVING COUNT(A.Ssex)>1;

18. 查询 1990 年出生的学生名单

-- 查询 1990 年出生的学生名单
-- 思路:学生信息表student中根据Sage查询1990年出生的学生。
select * from student where DATE_FORMAT(Sage,'%Y')='1990' ;

19. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

-- 根据课程进行分组查询平均成绩,再排序
select Cid,AVG(score) as '平均成绩' from sc GROUP BY Cid ORDER BY AVG(score) DESC,Cid ASC;

20. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩 

-- 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩 
-- 在成绩表sc中根据Sid查询每个学生的平均成绩,筛选得到平均成绩大于85的学生的Sid,平均成绩。然后根据得到的学生Sid采用join  on  或者两表联查的办法在学生信息表student中得到学生姓名。
-- 方法一:join on
-- 步骤一 在成绩表sc中根据Sid查询每个学生的平均成绩,筛选得到平均成绩大于85的学生的Sid,平均成绩。
select Sid,AVG(score) as '平均成绩' from sc GROUP BY Sid HAVING  AVG(score) >85; 
-- 步骤二 根据得到的学生Sid采用join  on在学生信息表student中得到学生姓名。
select student.Sid,Sname,A.`平均成绩` from student join (select Sid,AVG(score) as '平均成绩' from sc GROUP BY Sid HAVING  AVG(score) >85) as A on A.Sid = student.Sid;

-- 方法二:嵌套子查询
-- 步骤一 在成绩表sc中根据Sid查询每个学生的平均成绩,筛选得到平均成绩大于85的学生的Sid,平均成绩。
select Sid,AVG(score) as '平均成绩' from sc GROUP BY Sid HAVING  AVG(score) >85; 
-- 步骤二 根据得到的学生Sid采用两表联查在学生信息表student中得到学生姓名。
select Sname,A.Sid,A.`平均成绩` from student,(select Sid,AVG(score) as '平均成绩' from sc GROUP BY Sid HAVING  AVG(score) >85) as A where A.Sid=student.Sid ;

21. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数 

2021-04-09 09:23:47 星期五  打卡

-- 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数 
-- 涉及表课程表course,成绩表sc,学生信息表student
-- 思路:将课程表和成绩表根据Cid进行两表联查,查出分数低于60分的数学成绩的学生的Sid,再将的到的数据和学生信息表两表联查得到学生姓名。
select student.Sid,Sname,Cid,score from student JOIN (select Sid,course.Cid,score from sc JOIN course on course.Cid = sc.Cid where course.Cname='数学' and sc.score<60) as A on A.Sid = student.Sid;

22. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

2021-04-10  12:15:04  星期六  打卡

-- 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
-- 涉及表: 学生信息表student,课程表course,成绩表sc
-- 思路:根据student表得到所有学生的Sid,然后与sc表进行左连接查询,得到Cid,再与课程表左连接。
select A.Sid,A.Sname,course.Cid,Cname,A.score from course right JOIN (select student.Sid,Sname,Cid,score from student LEFT JOIN sc on sc.Sid=student.Sid)as A on A.Cid=course.Cid ORDER BY Sid,Cid;

23. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

2021-04-11  23:16:03  星期天  打卡

-- 涉及表:学生信息表student、成绩表sc、课程表course
-- 思路:在成绩表中先查询出成绩在70分以上的Sid、Cid和score,再与学生表进行联查得到姓名,再和成绩表进行联查得到课程名称。
select Sname,course.Cid,score from course join (select student.Sid,Cid,Sname,score from student join (select Sid,Cid,score from sc where score>70) as A on A.Sid =student.Sid) as B on B.Cid=course.Cid;

24. 查询不及格的课程

2021-04-12   09:40:36  星期一  打卡

-- 涉及表:成绩表sc,课程表course
-- 思路:根据成绩表查询出不及格的Cid,然后与课程表进行联查。
-- 方法一
select Cid,Cname from course where Cid in (select DISTINCT Cid from sc where score<60);
-- 方法二
select course.Cid,Cname from course join (select DISTINCT Cid from sc where score<60) as A on A.Cid=course.Cid; 

25. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

2021-04-13   09:20:03   星期二  打卡

-- 涉及表:成绩表sc,学生信息表student
-- 思路:现根据课程编号在成绩表中查询出课程编号为01的学生,在筛选出成绩大于80分以上的学生Sid,在根据Sid在学生信息表中查询
-- 方法一
select Sid ,Sname from student where Sid in (select Sid from sc where Cid=01 and score>80);
-- 方法二
select student.Sid,Sname from student join (select Sid,Cid,score from sc where Cid=01 and score>80) as A on A.Sid=student.Sid; 

26. 求每门课程的学生人数 

2021-04-14   09:24:24   星期三  打卡

-- 涉及表:成绩表sc,课程表student(考虑到有的课程一个学生都没有选)
-- 思路:在sc表中根据课程号进行分类求和,得出该门课程的学生人数,再和student表进行联查,得出每门课程的学生人数。
SELECT course.Cid,Cname,A.totals from course LEFT JOIN (SELECT Cid,count(Sid) as totals from sc GROUP BY Cid) as A on A.Cid=course.Cid;

27. 查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

2021-04-15   09:37:13  星期四  打卡

-- 涉及表:成绩表sc,教师表teacher,学生信息表student
-- 思路:根据teacher表查询张三老师得Cid,根据Cid在成绩表中查询学生得Sid和成绩,最后根据Sid在学生信息表中查询学生信息。
select student.Sid,Sname,Sage,Ssex,A.Cid,A.score from student join (select Cid,Sid,score from sc where Cid in (select Cid from teacher where Tname='张三')) as A on A.Sid =student.Sid;

28. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

2021-04-16   09:23:40   周五   打卡

-- 涉及表:成绩表sc,教师表teacher,课程表,学生信息表student
-- 思路:根据老师姓名在教师表中查询出老师的Tid,根据查询出来的Tid在课程表中查询出老师教授课程的Cid,再根据查询出来的Cid在成绩表中查询出成绩最高的学生Sid,再根据Sid在学生信息表中查询出学生信息。
select * from student join (SELECT Sid,score from sc JOIN (select Cid,MAX(score) as '最高分' from sc where Cid in (select Cid from course where Cid in (select Tid from teacher where Tname='张三'))) as A on A.Cid=sc.Cid and A.`最高分`=sc.score) as B on B.Sid = student.Sid; 

29. 分别查询各个课程,成绩相同的学生的学生编号、课程编号、学生成绩 

2021-04-17   22:34:48  星期六  打卡

-- 涉及表:成绩表sc ,学生信息表student
select * from student join (SELECT DISTINCT Sid, C.Cid,C.score from sc as C ,(select Cid,score,COUNT(score) from (select Cid,score from sc ORDER BY Cid ASC) as A GROUP BY A.score,A.Cid HAVING COUNT(score)>=2)as D WHERE C.Cid=D.Cid and C.score=D.score)as E on E.Sid=student.Sid;

30. 统计每门课程的学生选修人数(超过 5 人的课程才统计)。

2021-04-18   12:53:37  周天  打卡

-- 涉及表:成绩表sc 
select Cid,count(Sid) as '选修人数' from sc GROUP BY Cid HAVING count(Sid)>5;

31. 检索至少选修两门课程的学生学号 

2021-04-19  16:17:46  周一  打卡

-- 涉及表:成绩表sc 、学生信息表student
select * from student JOIN (select Sid,COUNT(Cid) from sc GROUP BY Sid HAVING COUNT(Cid)>=2)as A on A.Sid=student.Sid;

32. 查询选修了全部课程的学生信息

2021-04-20   09:35:07   周二  打卡

-- 涉及表:成绩表sc,课程表course,学生信息表student
-- 思路:根据课程表得知所有的课程的Cid,然后根据Cid在成绩表中查询出选修了全部Cid的学生得Sid,再根据Sid在student表中查询相关信息。
select * from student join (select Sid from sc GROUP BY Sid HAVING count(Cid)=(select COUNT(Cid) from course)) as A on A.Sid=student.Sid;

33. 查询各学生的年龄,只按年份来算 

2021-04-21   09:16:13   周三   打卡

-- 涉及表:学生信息表student
-- 思路:将当前时间的年份减去student表中Sage的年份即可。
select *,DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(Sage,'%Y') as '年龄' from student;

34. 查询本周过生日的学生

2021-04-24    13:30:57   周六   打卡

-- 涉及表:学生信息表student
-- 思路:查询Sage在本周的学生信息即可。
select * from student where Sage between current_date()-7 and sysdate();

-- 补充:https://www.cnblogs.com/Luouy/p/7590812.html

35. 查询下周过生日的学生

 2021-04-28  10:01:09  周三   打卡

-- 涉及表:学生信息表student
select * from student where YEARWEEK(DATE_FORMAT(Sage,'%Y-%m-%d')) = YEARWEEK(CURDATE()) + 1;
-- 参考地址:https://blog.csdn.net/weixin_30951389/article/details/95963715

36. 查询本月过生日的学生

2021-04-25   09:51:08   周日   打卡

-- 涉及表:学生信息表student
-- 思路:月初 CURDATE()   月末  LAST_DAY(CURDATE())
select * from student where Sage BETWEEN  DATE_FORMAT( CURDATE(),  ' %Y-%m-01 00:00:00 ' )  and  DATE_FORMAT( LAST_DAY(CURDATE()), '%Y-%m-%d 23:59:59');

37. 查询下月过生日的学生

2021-04-26   09:50:57   周一  打卡

-- 涉及表:成绩表sc
-- 思路:PERIOD_DIFF()函数返回两日期之间的差异。现在的时间减去时间字段=-1,即4月减去时间字段=-1,时间字段就等于5月,即下个月。结果以月份计算。PERIOD_DIFF(period1, period2)注意: period1 和 period2 应采用相同的格式。格式:YYMM或YYYYMM

-- 下月
SELECT * FROM student WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( Sage, '%Y%m' ) ) =-1;
-- 本月
SELECT * FROM student WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( Sage, '%Y%m' ) ) =0;
-- 上月
SELECT * FROM student WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( Sage, '%Y%m' ) ) =1;

-- 参考链接:https://www.begtut.com/sql/func-mysql-period-diff.html

38. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

2021-04-22   11:10:58   周四   打卡  

-- 涉及表:成绩表sc
-- 思路:先根据Sid,统计每个学生的选修课程数,再统计每个学生的总成绩,然后总成绩除以选修课程数得到平均成绩,再与sc表联查,得到所有学生所有课程的成绩。
select sc.*,D.`平均成绩` from sc,(select A.Sid,A.`总成绩`/ B.`选修科目数` as '平均成绩' from (select Sid,SUM(score) as '总成绩' from sc GROUP BY Sid)as A join  (select Sid,COUNT(Cid) as '选修科目数' from sc GROUP BY Sid) as B on B.Sid=A.Sid ORDER BY A.`总成绩`/ B.`选修科目数` DESC
)as D;

 

练习题来源:https://blog.csdn.net/flycat296/article/details/63681089

posted @ 2021-03-15 10:30  惜阙  阅读(517)  评论(0)    收藏  举报