- 建库
create database test default charset utf8;
- 创建class表 / 插入数据
-- 创建表 create table class ( cid int not null auto_increment primary key, caption char(12) not null, unique uq_cp(caption) ) engine=innodb auto_increment=1 default charset=utf8; -- 插入数据(多插入一些数据) insert into class(caption) values ("三年二班"),("一年三班"),("三年一班"),("三年三班"),("一年一班"),("一年二班");
- 创建teacher表 / 插入数据
-- 建表 create table teacher( tid int not null auto_increment primary key, tname varchar(24) not null ) engine=innodb auto_increment=1 default charset=utf8; -- 插入数据(多插入一些数据) insert into teacher(tname) values ("赵老师"),("钱老师"),("孙老师"),("李老师"),("周老师"),("马老师"),("王老师");
- 创建student表 / 插入数据
-- 建表 create table student( sid int not null auto_increment primary key, gender char(3) not null, sname varchar(24) not null, class_id int, constraint foreign key fk_std_cls (class_id) references class (cid) ) engine=innodb auto_increment=1 default charset=utf8; -- 插入数据(多插入一些数据) insert into student(gender, sname, class_id) values ("狗蛋","女","1"),("钢蛋","女","2"),("小名","男","3"),("小张","男","4"), ("小花","女","5"),("张三","男","6"),("马力","女","1"),("王五","女","2"), ("小孙","男","3"),("李三","男","4"),("周五","女","5"),("张爽","女","6");
- 创建course表 / 插入数据
-- 建表 create table course( cid int not null auto_increment primary key, cname varchar(24) not null, teacher_id int, constraint foreign key fk_cs_th (teacher_id) references teacher (tid) ) engine=innodb auto_increment=1 default charset=utf8; -- 插入数据(多插入一些数据) insert into course(cname, teacher_id) values ("数据库原理","1"),("系统分析与设计","2"),("会计学","3"),("商务智能","4"),("机器学习","5"),("R语言","6"), ("Python","7"),("Linux","1"),("微机原理","3"),("管理学","3"),("科技论文写作","1");
- 创建score表 / 插入数据
-- 建表 create table score( sid int not null auto_increment primary key, student_id int, course_id int, number tinyint, constraint foreign key fk_sc_cs (course_id) references course (cid), constraint foreign key fk_sc_st (student_id) references student (sid), unique uq_st_cs (student_id, course_id) ) engine=innodb auto_increment=1 default charset=utf8; -- 插入数据(多插入一些数据) insert into score(student_id, course_id, number) values (1,1,10),(2,1,20),(3,1,60),(4,1,70),(5,1,80),(6,2,100),(7,2,50),(1,2,20),(2,2,98),(3,2,88),(4,3,79),(9,3,90),(11,3,95),(1,3,6),(2,3,100),(3,4,11),(4,5,0),(1,6,21),(2,7,60),(5,8,71),(3,9,95),(1,4,61),(1,5,88),(1,7,99),(1,8,42),(1,9,78),(1,10,88),(1,11,82);
- 1、自行创建测试数据
-- 参照上一小节
- 2、查询“数据库原理”课程比“会计学”课程成绩高的所有学生的学号
-- SQL语句 select A.student_id from (select score.student_id, score.number, course.cname from score left join course on score.course_id=course.cid where course.cname='数据库原理') as A left join (select score.student_id, score.number, course.cname from score left join course on score.course_id=course.cid where course.cname='会计学') as B on A.student_id=B.student_id where A.number > B.number;
- 3、查询平均成绩大于60分的同学的学号和平均成绩;
-- SQL语句 select score.student_id, avg(number) as avg from score left join student on score.student_id=student.sid group by score.student_id having avg > 60;
- 4、查询所有同学的学号、姓名、选课数、总成绩;
-- SQL语句 -- [注意] :此处是所有同学 select student.sid,student.sname,ifnull(count(score.number), 0),ifnull(sum(score.number),0) from student left join score on student.sid=score.student_id group by student.sid;
- 5、查询姓“李”的老师的个数;
-- SQL语句 select count(1) from teacher where tname like '李%';
- 6、查询没学过“赵”老师课的同学的学号、姓名;
-- SQL语句 select score.student_id, student.sname from score left join course on score.course_id=course.cid left join student on score.student_id=student.sid where score.course_id in ( select cid from course left join teacher on course.teacher_id=teacher.tid where teacher.tname="赵老师" ) group by score.student_id;
- 7、查询学过“1”并且也学过编号“2”课程的同学的学号、姓名;
-- SQL语句 select student.sid,student.sname from student left join score on student.sid=score.student_id where score.course_id=1 or score.course_id=2 group by student.sid; -- 去重:除了用group by之外,还可以用distinct,但是效率较低
- 8、查询学过“赵老师”所教的所有课的同学的学号、姓名;
-- SQL语句 select score.student_id,student.sname,count(1) from score left join student on score.student_id=student.sid where score.course_id in (select course.cid from course left join teacher on course.teacher_id=teacher.tid where teacher.tname like '赵%') group by score.student_id having count(1)=(select count(1) from course left join teacher on course.teacher_id=teacher.tid where teacher.tname like '赵%');
- 9、查询课程编号“2”的成绩比课程编号“1”课程成绩高的所有同学的学号、姓名;
-- SQL语句 select * from (select student_id,course_id,number from score where course_id=1) as A inner join (select student_id,course_id,number from score where course_id=2) as B on A.student_id=B.student_id where A.number < B.number;
- 10、查询有课程成绩小于60分的同学的学号、姓名;
-- SQL语句 select score.student_id,student.sname from score left join student on score.student_id=student.sid where score.number < 60 group by score.student_id;
- 11、查询没有学全所有课的同学的学号、姓名;
-- SQL语句 select score.student_id,student.sname from score left join student on score.student_id=student.sid group by score.student_id having count(1) < (select count(1) from course);
- 12、查询至少有一门课与学号为“3”的同学所学相同的同学的学号和姓名;
-- SQL语句 select score.student_id,student.sname from score left join student on score.student_id=student.sid where score.course_id in (select course_id from score where score.student_id=3) and score.student_id != 3 group by score.student_id;
- 13、查询至少学过学号为“1”同学所选课程中任意一门课的其他同学学号和姓名;
-- SQL语句 -- [说明]:至少与学生2学的课一样多,或者比他学的多 select score.student_id,student.sname from score left join student on score.student_id=student.sid where score.course_id in (select course_id from score where score.student_id=1) and score.student_id != 1 group by score.student_id having count(1) = (select count(1) from score where score.student_id=1);
- 14、查询和“2”号的同学学习的课程完全相同的其他同学学号和姓名;
-- SQL语句 select score.student_id,student.sname from score left join student on score.student_id=student.sid where score.student_id in ( select student_id from score where score.student_id != 2 group by score.student_id having count(1)=(select count(1) from score where score.student_id=2) ) group by student_id having count(1)=(select count(1) from score where score.student_id=2);
- 15、删除学习“马老师”课的score表记录;
-- SQL语句 delete from score where course_id in ( select course.cid from course left join teacher on course.teacher_id=teacher.tid where teacher.tname='马老师' );
- 16、向score表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“2”课程的同学学号;②插入“2”号课程的平均成绩;
-- SQL语句 insert into score(student_id, course_id, number) ( select sid,2,(select avg(number) from score where score.course_id=2) from student where sid not in (select student_id from score where score.course_id=2) ); -- [注意]:判断没上过2号课程同学的学号,应当先确定上过该课程同学的学号,然后再进行排除;如果过程反过来了,则会出错!
- 17、按平均成绩从低到高显示所有学生的“数据库原理”、“系统分析与设计”、“会计学”三门的课程成绩,按如下形式显示: 学生ID,数据库原理,系统分析与设计,会计学,有效课程数,有效平均分;
-- SQL语句 select student_id, ( select s2.number from score as s2 inner join course on s2.course_id=course.cid where s2.student_id=s1.student_id and course.cname="数据库原理" ) as db, ( select s2.number from score as s2 inner join course on s2.course_id=course.cid where s2.student_id=s1.student_id and course.cname="系统分析与设计" ) as sys, ( select s2.number from score as s2 inner join course on s2.course_id=course.cid where s2.student_id=s1.student_id and course.cname="会计学" ) as calc, count(1) as course_num, avg(s1.number) as avg from score as s1 group by s1.student_id order by avg desc;
- 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
-- SQL语句 select course_id,max(number) as max,min(number) as min from score group by course_id;
- 19、按各科平均成绩从低到高和及格率的百分数从高到低排序;
-- SQL语句 select course_id, avg(number) as avg, sum(case when number > 60 then 1 else 0 end)/count(1) as percent from score group by course_id order by avg desc; -- [注意]:case when ... then ... else ... end --> (三目运算符)
- 20、课程平均分从高到低显示(现实任课老师);
-- SQL语句 select score.course_id, avg(score.number) as avg, teacher.tname from score left join course on score.course_id=course.cid left join teacher on course.teacher_id=teacher.tid group by score.course_id order by avg desc;
- 21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
-- SQL语句 select s1.course_id, (select number from score as s2 where s2.course_id=s1.course_id group by number order by number desc limit 0,1) as first_person, (select number from score as s2 where s2.course_id=s1.course_id group by number order by number desc limit 1,1) as second_person, (select number from score as s2 where s2.course_id=s1.course_id group by number order by number desc limit 2,1) as third_person from score as s1 group by course_id;
- 22、查询每门课程被选修的学生数;
-- SQL语句 select course.cid, course.cname, count(1) from course left join score on course.cid=score.course_id group by course.cid;
- 23、查询出只选修了一门课程的全部学生的学号和姓名;
-- SQL语句 -- 方法一 select sid, sname from student where sid in ( select student_id from score group by student_id having count(1)=1 ); -- 方法二 select student.sid,student.sname from student left join score on student.sid=score.student_id group by student.sid having count(1)=1;
- 24、查询男生、女生的人数;
-- SQL语句 select gender,count(1) from student group by gender;
- 25、查询姓“张”的学生名单;
-- SQL语句 select sid,sname from student where sname like '张%';
- 26、查询同名同姓学生名单,并统计同名人数;
-- 由于原始数据库中没有同名同姓的人,故先插入一部分数据 insert into student(sname,gender,class_id) (select sname,gender,class_id from student limit 0,2); insert into student(sname,gender,class_id) (select sname,gender,class_id from student limit 0,4); -- SQL语句 select sname,count(1) from student group by sname having count(1) >=2;
- 27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
-- SQL语句 select course_id,course.cname,avg(number) as avg from score left join course on score.course_id=course.cid group by course_id order by avg asc, course_id desc;
- 28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
-- SQL语句 select student_id,student.sname,avg(number) as avg from score left join student on score.student_id=student.sid group by student_id having avg > 85;
- 29、查询课程名称为“数据库原理”,且分数低于60的学生姓名和分数;
-- SQL语句 select student_id,student.sname,score.number from score left join student on score.student_id=student.sid where score.course_id=(select cid from course where cname='数据库原理') and number < 60;
- 30、查询课程编号为3且课程成绩在80分以上的学生的学号和姓名;
-- SQL语句 select score.student_id,student.sname from score left join student on score.student_id=student.sid where course_id=3 and number>80;
- 31、求选了课程的学生人数
-- SQL语句 select count(s1.student_id) as course_count from ( select student_id from score group by student_id ) as s1;
- 32、查询选修“赵老师”所授课程的学生中,成绩最高的学生姓名及其成绩;
-- SQL语句 select student.sname,score.number from score left join student on score.student_id=student.sid where course_id in ( select cid from course where teacher_id=(select tid from teacher where tname='赵老师') ) order by number desc limit 0,1;
- 33、查询各个课程及相应的选修人数(注意是全部课程);
-- SQL语句 select course.cid,count(1) from course left join score on course.cid=score.course_id group by course.cid;
- 34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
-- SQL语句 -- 使用笛卡尔积 select s1.student_id,s2.student_id,s1.course_id,s1.number from score as s1, score as s2 where s1.course_id != s2.course_id and s1.number = s2.number;
- 35、查询每门课程成绩最好的前两名;
-- SQL语句 select course_id, (select student_id from score as s2 where s2.course_id=s1.course_id order by number desc limit 0,1) as stu_id_first, (select number from score as s2 where s2.course_id=s1.course_id order by number desc limit 0,1) as stu_score_first, (select student_id from score as s2 where s2.course_id=s1.course_id order by number desc limit 1,1) as stu_id_second, (select number from score as s2 where s2.course_id=s1.course_id order by number desc limit 1,1) as stu_score_second from score as s1 group by course_id;
- 36、检索至少选修两门课程的学生学号;
-- SQL语句 -- 此处博主额外显示了每个学生选修的课程数 select student_id,count(1) from score group by student_id having count(1) >= 2;
- 37、查询全部学生都选修的课程的课程号和课程名;
-- 所有课程中没有一门课被全部学生选修,因此先插入一些数据 insert into score(student_id,course_id,number) values (6,1,10),(7,1,20),(8,1,30),(9,1,60),(10,1,77),(11,1,80),(12,1,91),(7,3,69),(8,3,49),(12,3,72),(10,3,59); -- SQL语句 select s1.course_id from( select course_id,count(1) as cut from score group by course_id ) as s1 left join course on s1.course_id=course.cid where s1.cut=( select count(1) from student );
- 38、查询没学过“孙老师”讲授的任一门课程的学生姓名;
-- SQL语句 -- 需要先查询选修过孙老师课程的学生的学号,然后再排除 -- 博主附带查询了学生的学号 select sid,sname from student where sid not in ( select student_id from score left join course on score.course_id = course.cid where teacher_id = (select tid from teacher where tname='孙老师') group by student_id );
- 39、查询两门以上不及格课程的同学的学号及其平均成绩;
-- SQL语句 select student_id,count(1) as count,avg(number) as avg from score where number < 60 group by student_id having count > 2;
- 40、检索“4”号课程分数小于60,按分数降序排列的同学学号;
-- SQL语句 select course_id,student_id,number from score where course_id = 4 and number < 60 order by number desc;
- 41、删除“2”号同学的“1”号课程的成绩;
-- 先查询看是否有对应成绩 select * from score where student_id = 2 and course_id =1; -- SQL语句 delete from score where student_id = 2 and course_id = 1; -- 确认一下是否已经删除 select * from score where student_id = 2 and course_id =1;