准备表:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
create table class(cid int primary key auto_increment, caption char(5) not null unique); INSERT into class(caption)values('三年二班'),('一年三班'),('三年一班'); CREATE table student(sid int primary key auto_increment, sname char(6) not null, gender enum('男','女','male','female') not null, class_id int(4) not null, foreign key(class_id) references class(cid) on delete CASCADE on update cascade); insert into student(sname,gender,class_id)values ('钢蛋','女',1),('铁锤','女',1),('山炮','男',2); create table teacher(tid int primary key auto_increment, tname char(6) not null); insert into teacher(tname)values('波多'),('苍空'),('饭岛'); create table course(cid int primary key auto_increment, cname CHAR(5) not null unique, teacher_id int not null, foreign key(teacher_id) references teacher(tid) on delete CASCADE on update cascade); insert into course(cname,teacher_id)values('生物',1),('体育',1),('物理',2); create table score(sid int primary key auto_increment, student_id int not null, foreign key(student_id) references student(sid) on delete cascade on update cascade, course_id int not null, foreign key(course_id) references course(cid) on delete cascade on update cascade, number int(4) not null); insert into score(student_id,course_id,number)values(1,1,60),(1,2,59),(2,2,100); SELECT * from class; show CREATE table class; select * from student; show create table student; SELECT * from teacher; show create table teacher; select * from course; show create table course; select * from score; show create table score;
开始练习:
1、查询所有的课程的名称以及对应的任课老师姓名 SELECT cname,tname from course inner join teacher ON course.teacher_id = teacher.tid; 2、查询学生表中男女生各有多少人 select gender,COUNT(sid) from student GROUP BY gender; 3、查询物理成绩等于100的学生的姓名 SELECT sname from student where sid in ( SELECT student_id from score where course_id = (SELECT cid from course where cname = '物理') and num = 100 ); 4、查询平均成绩大于八十分的同学的姓名和平均成绩 方法1: SELECT student.sname,t1.avg_num from student inner join (SELECT student_id,AVG(num) avg_num from score GROUP BY student_id HAVING avg(num) > 80) as t1 on student.sid = t1.student_id; 方法2: select * from student where sid in ( select student_id from score group by student_id having avg(num)>80 ); 5、查询所有学生的学号,姓名,选课数,总成绩 SELECT student.sid,student.sname,t1.course_num,t1.total_num from student inner JOIN (SELECT student_id, count(course_id) course_num, sum(num) total_num FROM score GROUP BY student_id) as t1 on student.sid = t1.student_id; 6、 查询姓李老师的个数 方法1: SELECT COUNT(1) from teacher where tname like '李%'; 方法2: select count(t1) from ( select tname t1 from teacher where tname LIKE '李%' )as t 7、 查询没有报李平老师课的学生姓名 SELECT sname FROM student WHERE sid NOT IN ( SELECT student_id FROM score WHERE course_id IN ( SELECT cid FROM course WHERE teacher_id = ( SELECT tid FROM teacher WHERE tname = '李平老师' ) ) ); 8、 查询物理课程比生物课程高的学生的学号 SELECT t1.student_id from (SELECT student_id,num from score where course_id = ( SELECT cid from course where cname = '物理' )) as t1 inner join (SELECT student_id,num from score where course_id = ( SELECT cid from course where cname = '生物' )) as t2 on t1.student_id = t2.student_id where t1.num > t2.num; 9、 查询没有同时选修物理课程和体育课程的学生姓名 方法1: SELECT sname from student where sid in ( SELECT student_id from score LEFT JOIN course on score.course_id = course.cid WHERE course.cname in ('物理','体育') GROUP BY student_id HAVING count(sid) < 2 ); 方法2: select sname from student where sid not in ( SELECT s1.student_id from ( select student_id from score where course_id =( SELECT cid from course where cname ='体育')) s1 INNER JOIN ( select student_id from score where course_id =( SELECT cid from course where cname ='物理')) s2 on s1.student_id=s2.student_id); 10、查询挂科超过两门(包括两门)的学生姓名和班级 方法1:: SELECT sname,caption from student LEFT JOIN class on student.class_id = class.cid where student.sid in ( SELECT student_id from score where num < 60 GROUP BY student_id HAVING COUNT(course_id) >= 2 ) ; 方法2: select s.sname,class.caption from class INNER JOIN (select * from student where sid in ( select student_id from score GROUP BY student_id having student_id>=2)) s on s.class_id=class.cid; 11 、查询选修了所有课程的学生姓名 select sname from student where sid in ( select student_id from score GROUP BY student_id having count(sid)=( select count(cid) from course)) 12、查询李平老师教的课程的所有成绩记录 方法1: SELECT * from score where course_id in ( SELECT cid from course inner JOIN teacher on course.teacher_id = teacher.tid WHERE tname = '李平老师' ); 方法2: select num from score WHERE course_id in ( select cid from course where teacher_id=( select tid from teacher where tname='李平老师')); 13、查询全部学生都选修了的课程号和课程名 SELECT ss.s1,ss.s2,course.cid,course.cname from (select student.sid s1,student.sname s2,score.course_id s3 from student INNER JOIN score on student.sid=score.student_id ) ss INNER JOIN course on ss.s3=course.cid; 14、查询每门课程被选修的次数 方法1: SELECT course.cname,t1.count_student FROM course INNER JOIN ( SELECT course_id,count(student_id) count_student from score GROUP BY course_id ) as t1 ON course.cid = t1.course_id; 方法2: select course.cname,COUNT(score.sid) from course INNER JOIN score on course.cid=score.course_id group by score.course_id; 15、查询只选修了一门课程的学生姓名和学号 select sid,sname from student where sid in( select student_id from score GROUP BY student_id having count(sid)=1); 16、查询所有学生考出的总成绩并按从高到低排序(成绩去重) 方法1: SELECT DISTINCT sum(num) sum_num from score group by student_id ORDER BY sum_num desc; 方法2: select student.sname,avg(score.num) avg_num from student INNER JOIN score on student.sid=score.student_id GROUP BY student_id ORDER BY avg_num desc; 17、查询平均成绩大于85的学生姓名和平均成绩 方法1: SELECT student.sname,t1.avg_num from student inner join ( SELECT student_id,avg(num) avg_num from score GROUP BY student_id having avg(num) > 85 ) as t1 on student.sid = t1.student_id; 方法2: select student.sname,avg(score.num) from student INNER JOIN score on student.sid=score.student_id GROUP BY score.student_id having avg(score.num)>85; 18、查询生物成绩不及格的学生姓名和对应生物分数 方法1: SELECT sname,t1.num from student INNER JOIN ( SELECT student_id,num from score LEFT JOIN course on score.course_id = course.cid where course.cname = '生物' and score.num < 60 ) as t1 on student.sid = t1.student_id; 方法2: select student.sname,ss.num from student INNER JOIN( select * from score where course_id=( select cid from course where cname='生物') and num<60) ss on ss.student_id=student.class_id; 19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名 select sname from student where sid in( select student_id from score where course_id in( select cid from course where teacher_id=( select tid from teacher where tname='李平老师')) GROUP BY student_id HAVING avg(num)=( select avg(num) from score where course_id in( select cid from course where teacher_id=( select tid from teacher where tname='李平老师')) GROUP BY student_id order by avg(num) desc limit 1)) 20、查询每门课程成绩最好的前两名学生姓名 SELECT * from score ORDER BY course_id,num desc; #取得课程编号与第一高的成绩:course_id,first_num SELECT course_id,max(num) first_num from score GROUP BY course_id; #取得课程编号与第二高的成绩:course_id,second_num SELECT score.course_id,max(num) second_num from score LEFT JOIN ( SELECT course_id,max(num) first_num from score GROUP BY course_id ) as t1 on score.course_id = t1.course_id where score.num < t1.first_num GROUP BY score.course_id ; #链表得到一张新表,新表包含课程编号与这门课程前两名的成绩分数 select t1.course_id,t1.first_num,t2.second_num from (SELECT course_id,max(num) first_num from score GROUP BY course_id) as t1 inner join (SELECT score.course_id,max(num) second_num from score LEFT JOIN ( SELECT course_id,max(num) first_num from score GROUP BY course_id ) as t1 on score.course_id = t1.course_id where score.num < t1.first_num GROUP BY score.course_id) as t2 on t1.course_id = t2.course_id; #取前两名学生的编号 SELECT score.course_id,score.student_id from score LEFT JOIN ( select t1.course_id,t1.first_num,t2.second_num from (SELECT course_id,max(num) first_num from score GROUP BY course_id) as t1 inner join (SELECT score.course_id,max(num) second_num from score LEFT JOIN ( SELECT course_id,max(num) first_num from score GROUP BY course_id ) as t1 on score.course_id = t1.course_id where score.num < t1.first_num GROUP BY score.course_id) as t2 on t1.course_id = t2.course_id ) as t3 on score.course_id = t3.course_id where score.num >= t3.second_num and score.num <= t3.first_num ; SELECT t4.course_id,student.sname from student inner join ( SELECT score.course_id,score.student_id from score LEFT JOIN ( select t1.course_id,t1.first_num,t2.second_num from (SELECT course_id,max(num) first_num from score GROUP BY course_id) as t1 inner join (SELECT score.course_id,max(num) second_num from score LEFT JOIN ( SELECT course_id,max(num) first_num from score GROUP BY course_id ) as t1 on score.course_id = t1.course_id where score.num < t1.first_num GROUP BY score.course_id) as t2 on t1.course_id = t2.course_id ) as t3 on score.course_id = t3.course_id where score.num >= t3.second_num and score.num <= t3.first_num ) as t4 on student.sid = t4.student_id ORDER BY t4.course_id ; select student.sname,t.course_id,t.num from student INNER JOIN ( select s1.student_id,s1.course_id,s1.num, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1,1) as second_num from score as s1 ) as t on student.sid = t.student_id where t.num in (t.first_num,t.second_num) ORDER BY t.course_id ; SELECT sid from score as s1 ;