Mysql 查询练习
Mysql 查询练习
---创建班级表 create table class( cid int auto_increment primary key, caption varchar(20) )engine=innodb default charset=utf8; ---创建学生表 create table student( sid int auto_increment primary key, sname varchar(20), gender varchar(10) default '男', class_id int )engine=innodb default charset=utf8; insert into student(sname,gender,class_id) values('范冰冰','女','3'); ---创建老师表 create table teacher( tid int auto_increment primary key, tname varchar(20) )engine=innodb default charset=utf8; mysql> insert into teacher(tname) values('孙子'); mysql> update teacher set tname='李时珍' where tid=3; ---创建课程表 create table course( cid int auto_increment primary key, cname varchar(20), teache_id int )engine=innodb default charset=utf8; mysql> insert into course(cname) value('本草纲目'); ---创建学生成绩表 create table score( sid int auto_increment primary key, student_id int, corse_id int, number int )engine=innodb default charset=utf8; insert into score(student_id,corse_id,number) values(1,1,90); mysql> insert into score(student_id,corse_id,number) values(1,3,58); update score set corse_id=2 where student_id=3; ---设置主外键约束 ---学生表中class_id 关联class表中的cid alter table student add constraint fk_s_c foreign key student(class_id) references class(cid);
1、自行创建测试数据
2、查询“生物”课程比“物理”课程成绩高的所有学生的学号;
---先查出所有的生物课 学生成绩 mysql> select * from score where corse_id='001'; +-----+------------+----------+--------+ | sid | student_id | corse_id | number | +-----+------------+----------+--------+ | 1 | 1 | 1 | 90 | | 7 | 19 | 1 | 100 | | 10 | 18 | 1 | 98 | | 13 | 17 | 1 | 90 | | 16 | 16 | 1 | 70 | | 19 | 15 | 1 | 98 | | 22 | 14 | 1 | 76 | | 25 | 13 | 1 | 96 | | 28 | 12 | 1 | 74 | | 31 | 11 | 1 | 90 | | 34 | 10 | 1 | 83 | | 37 | 9 | 1 | 77 | | 41 | 8 | 1 | 96 | | 45 | 7 | 1 | 88 | | 48 | 6 | 1 | 60 | | 51 | 5 | 1 | 57 | | 54 | 4 | 1 | 86 | | 57 | 3 | 1 | 79 | | 60 | 2 | 1 | 43 | +-----+------------+----------+--------+ 19 rows in set (0.00 sec) ---查处所有学生物理课 学生成绩 select * from score where corse_id='003'; ------查询“生物”课程比“物理”课程成绩高的所有学生的学号: select a.student_id as '学号', a.number as '生物成绩',b.number as '物理成绩' from (select * from score where corse_id='001') a left join (select * from score where corse_id='003') b on a.student_id=b.student_id where a.number>b.number; +--------+--------------+--------------+ | 学号 | 生物成绩 | 物理成绩 | +--------+--------------+--------------+ | 1 | 90 | 58 | | 18 | 98 | 96 | | 17 | 90 | 80 | | 15 | 98 | 86 | | 13 | 96 | 72 | | 11 | 90 | 76 | | 10 | 83 | 81 | | 9 | 77 | 66 | | 8 | 96 | 84 | | 3 | 79 | 53 | +--------+--------------+--------------+ 10 rows in set (0.00 sec) -------------------------------------------------- select score.student_id as '学号', score.corse_id as '课程编号',course.cname as '课程名称', score.number as '成绩' from score,course where corse_id=1 and score.corse_id = course.cid; --------------------------------------------------- select score.corse_id as '课程编号',course.cname as '课程名称' from score,course where score.corse_id = course.cid group by corse_id; ----为表起别名: select a.corse_id as '课程编号',b.cname as '课程名称' from score a,course b where a.corse_id = b.cid group by corse_id; +--------------+--------------+ | 课程编号 | 课程名称 | +--------------+--------------+ | 1 | 生物 | | 2 | 体育 | | 3 | 物理 | +--------------+--------------+ ---------------------------------------------------
3、查询平均成绩大于60分的同学的学号和平均成绩;
---由于成绩录入的较高,这里查询平均成绩大于80分的同学的学号和平均成绩; select student_id as '学号',sum(number) as '总成绩',avg(number) as '平均成绩' from score where avg(number)>80 group by student_id; select student_id as '学号',sum(number) as '总成绩',avg(number) as '平均成绩' from score group by student_id; ---加having条件子句 select student_id as '学号',sum(number) as '总成绩',avg(number) as '平均成绩' from score group by student_id having avg(number)>80 ; +--------+-----------+--------------+ | 学号 | 总成绩 | 平均成绩 | +--------+-----------+--------------+ | 4 | 99 | 99.0000 | | 10 | 83 | 83.0000 | | 12 | 164 | 82.0000 | | 13 | 92 | 92.0000 | | 14 | 165 | 82.5000 | | 15 | 184 | 92.0000 | | 16 | 166 | 83.0000 | | 17 | 175 | 87.5000 | | 19 | 200 | 100.0000 | +--------+-----------+--------------+ 9 rows in set (0.27 sec)
4、查询所有同学的学号、姓名、选课数、总成绩;
---先从成绩表中查询相关信息: select student_id as '学号',count(*) as '选课数',sum(number) as '总成绩' from score group by student_id; +--------+-----------+-----------+ | 学号 | 选课数 | 总成绩 | +--------+-----------+-----------+ | 1 | 2 | 148 | | 2 | 2 | 146 | | 4 | 1 | 99 | | 5 | 2 | 133 | | 8 | 2 | 149 | | 9 | 2 | 152 | | 10 | 1 | 83 | | 12 | 2 | 164 | | 13 | 1 | 92 | | 14 | 2 | 165 | | 15 | 2 | 184 | | 16 | 2 | 166 | | 17 | 2 | 175 | | 19 | 2 | 200 | +--------+-----------+-----------+ 14 rows in set (0.00 sec) ---关联学生表查出学生姓名: select a.student_id,a.count(*),a.sum(number),b.sid from score a, student b group by a.student_id having a.student_id=b.sid; ---OK select student_id as '学号',student.sname as '学生姓名', count(*) as '选课数',sum(number) as '总成绩' from score left join student on score.student_id=student.sid group by student_id; +--------+--------------+-----------+-----------+ | 学号 | 学生姓名 | 选课数 | 总成绩 | +--------+--------------+-----------+-----------+ | 1 | 王小虎 | 3 | 228 | | 2 | 王小龙 | 2 | 146 | | 4 | 赵小四 | 1 | 99 | | 5 | 张小丽 | 2 | 133 | | 8 | 刘德华 | 3 | 189 | | 9 | 梁朝伟 | 2 | 152 | | 10 | 张学友 | 1 | 83 | | 12 | 张曼玉 | 2 | 164 | | 13 | 章子怡 | 1 | 92 | | 14 | 李晨 | 3 | 247 | | 15 | 王祖蓝 | 2 | 184 | | 16 | 陈赫 | 2 | 166 | | 17 | 邓超 | 2 | 175 | | 19 | 范冰冰 | 2 | 200 | +--------+--------------+-----------+-----------+ 14 rows in set (0.00 sec)
5、查询姓“李”的老师的个数;
mysql> select count(*) as '姓李 老师人数' from teacher where tname like '李%'; +---------------------+ | 姓李 老师人数 | +---------------------+ | 6 | +---------------------+ 1 row in set (0.00 sec)
6、查询没学过“司马迁”老师课的同学的学号、姓名;
----先从成绩表中查出没有学过‘司马迁’老师课程的学生学号。 mysql> select student_id from score where corse_id!=2 group by student_id; +------------+ | student_id | +------------+ | 2 | | 4 | | 5 | | 9 | | 12 | | 14 | | 15 | | 16 | | 19 | +------------+ 9 rows in set (0.00 sec) -------OK------------------------------------------------- select a.student_id as '学号', b.sname as '学生姓名' from score a ,student b where a.corse_id!=2 and a.student_id=b.sid group by a.student_id; +--------+--------------+ | 学号 | 学生姓名 | +--------+--------------+ | 2 | 王小龙 | | 4 | 赵小四 | | 5 | 张小丽 | | 9 | 梁朝伟 | | 12 | 张曼玉 | | 14 | 李晨 | | 15 | 王祖蓝 | | 16 | 陈赫 | | 19 | 范冰冰 | +--------+--------------+ 9 rows in set (0.00 sec)
7、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
select student_id from score where corse_id=1 union select student_id from score where corse_id=2; --------OK--------------------------------------- select student_id,student.sname from score left join student on score.student_id=student.sid where corse_id=1 union select student_id,student.sname from score left join student on score.student_id=student.sid where corse_id=2; +------------+-----------+ | student_id | sname | +------------+-----------+ | 19 | 范冰冰 | | 15 | 王祖蓝 | | 14 | 李晨 | | 1 | 王小虎 | | 8 | 刘德华 | | 17 | 邓超 | | 16 | 陈赫 | | 13 | 章子怡 | | 12 | 张曼玉 | | 10 | 张学友 | | 9 | 梁朝伟 | | 5 | 张小丽 | | 2 | 王小龙 | +------------+-----------+ 13 rows in set (0.00 sec)
8、查询学过“李时珍”老师所教的所有课的同学的学号、姓名;
---首先:李时珍 老师教:生物 和 物理 ---先从成绩表中查出学过‘李时珍’老师课的同学的信息; mysql> select * from score where corse_id=3 or corse_id=1; +-----+------------+----------+--------+ | sid | student_id | corse_id | number | +-----+------------+----------+--------+ | 7 | 19 | 1 | 100 | | 18 | 16 | 3 | 88 | | 19 | 15 | 1 | 98 | | 21 | 15 | 3 | 86 | | 22 | 14 | 1 | 76 | | 24 | 14 | 3 | 89 | | 30 | 12 | 3 | 95 | | 39 | 9 | 3 | 66 | | 53 | 5 | 3 | 76 | | 56 | 4 | 3 | 99 | | 62 | 2 | 3 | 93 | +-----+------------+----------+--------+ 11 rows in set (0.00 sec) --OK-联合学生表,查找学生姓名 select a.student_id, b.sname from score a,student b where (a.corse_id=3 or a.corse_id=1) and a.student_id = b.sid group by student_id; +------------+-----------+ | student_id | sname | +------------+-----------+ | 2 | 王小龙 | | 4 | 赵小四 | | 5 | 张小丽 | | 9 | 梁朝伟 | | 12 | 张曼玉 | | 14 | 李晨 | | 15 | 王祖蓝 | | 16 | 陈赫 | | 19 | 范冰冰 | +------------+-----------+ 9 rows in set (0.00 sec)
9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
select student_id as '学号',student.sname as '学生姓名' from score left join student on score.student_id=student.sid where corse_id=1 group by student_id having ;
10、查询所有课程成绩小于60分的同学的学号、姓名;
select student_id as '学号',student.sname as '学生姓名' from score left join student on score.student_id=student.sid where corse_id=1 group by student_id having ; select student_id as '学号',student.sname as '学生姓名' from score left join student on score.student_id=student.sid where number<60; ---OK--- select student_id as '学号',student.sname as '学生姓名', course.cname as '课程名称',score.number as '成绩 (小于60分)' from score left join (student,course) on score.student_id=student.sid and score.corse_id=course.cid where number<60; +--------+--------------+--------------+----------------------+ | 学号 | 学生姓名 | 课程名称 | 成绩 (小于60分) | +--------+--------------+--------------+----------------------+ | 5 | 张小丽 | 体育 | 57 | | 2 | 王小龙 | 体育 | 53 | | 1 | 王小虎 | 体育 | 58 | | 8 | 刘德华 | 生物 | 40 | +--------+--------------+--------------+----------------------+ 4 rows in set (0.00 sec) --课上老师要求测试练习 --成绩表score 关联学生表student 和 课程表course select score.sid,student_id as '学号',student.sname as '学生姓名',corse_id as '课程ID', course.cname as '课程名称',score.number as '成绩' from score left join (student,course) on score.student_id=student.sid and score.corse_id=course.cid order by score.sid;
11、查询没有学全所有课的同学的学号、姓名;
---思路:首先从成绩表中查出:每位学生各自所学的课程总数。
select student_id as '学号',student.sname as '学生姓名',count(student_id) as '所学课程总数' from score left join student on score.student_id=student.sid group by student_id; +--------+--------------+--------------------+ | 学号 | 学生姓名 | 所学课程总数 | +--------+--------------+--------------------+ | 1 | 王小虎 | 3 | | 2 | 王小龙 | 2 | | 4 | 赵小四 | 1 | | 5 | 张小丽 | 2 | | 8 | 刘德华 | 3 | | 9 | 梁朝伟 | 2 | | 10 | 张学友 | 1 | | 12 | 张曼玉 | 2 | | 13 | 章子怡 | 1 | | 14 | 李晨 | 3 | | 15 | 王祖蓝 | 2 | | 16 | 陈赫 | 2 | | 17 | 邓超 | 2 | | 19 | 范冰冰 | 2 | +--------+--------------+--------------------+ 14 rows in set (0.00 sec) ---然后,增加判断条件,筛选出‘所学课程总数’小于3的同学。 ---最后得到:没有学全所有课的同学的学号、姓名。 select student_id as '学号',student.sname as '学生姓名',count(student_id) as '所学课程总数' from score left join student on score.student_id=student.sid group by student_id having count(student_id)<3; +--------+--------------+--------------------+ | 学号 | 学生姓名 | 所学课程总数 | +--------+--------------+--------------------+ | 2 | 王小龙 | 2 | | 4 | 赵小四 | 1 | | 5 | 张小丽 | 2 | | 9 | 梁朝伟 | 2 | | 10 | 张学友 | 1 | | 12 | 张曼玉 | 2 | | 13 | 章子怡 | 1 | | 15 | 王祖蓝 | 2 | | 16 | 陈赫 | 2 | | 17 | 邓超 | 2 | | 19 | 范冰冰 | 2 | +--------+--------------+--------------------+ 11 rows in set (0.26 sec)
12、查询至少有一门课与学号为“001”的同学所学的课程 相同的同学的学号和姓名;
---思路: 先查询了解一下【学号为“001”的同学所学的课程】
select student_id as '学号',student.sname as '学生姓名',corse_id from score left join student on score.student_id=student.sid where student_id=1; +--------+--------------+----------+ | 学号 | 学生姓名 | corse_id | +--------+--------------+----------+ | 1 | 王小虎 | 3 | | 1 | 王小虎 | 2 | | 1 | 王小虎 | 1 | +--------+--------------+----------+ 3 rows in set (0.00 sec) ---然后,我们用如下类似语法:select * from 表 where id in (select nid from 表); 上边的语句改成如下语句 当作in后边的查询条件: select corse_id from score where student_id=1; ---继续 where条件中:student_id!=1是除了自身的意思。 select student_id as '学号',student.sname as '学生姓名',corse_id from score left join student on score.student_id=student.sid where corse_id in(select corse_id from score where student_id=1) and student_id!=1 order by student_id; +--------+--------------+----------+ | 学号 | 学生姓名 | corse_id | +--------+--------------+----------+ | 2 | 王小龙 | 2 | | 2 | 王小龙 | 3 | | 4 | 赵小四 | 3 | | 5 | 张小丽 | 3 | | 5 | 张小丽 | 2 | | 8 | 刘德华 | 3 | | 9 | 梁朝伟 | 2 | | 17 | 邓超 | 1 | | 19 | 范冰冰 | 2 | | 19 | 范冰冰 | 1 | +--------+--------------+----------+ 25 rows in set (0.00 sec)
13、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;
查询至少学过学号为“001”同学所有课的其他同学学号和姓名;
--思路 先取出学好为1的学生学过的课程: select corse_id from score where student_id = 1; +----------+ | corse_id | +----------+ | 3 | | 2 | | 1 | +----------+ --先取出和01完全相同的 然后再统计一遍选课个数大于01所选的个数; select count(corse_id) from score where student_id=1; --- select student_id as '学号',student.sname as '学生姓名' from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“002”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id /*分组条件:在上方查询条件的基础上,保证学习的课程总数相同*/ having count(score.corse_id)=(select count(corse_id) from score where student_id=1) order by student_id; 先选出和1全部相同的,让后选个数大于等于01的; select a.student_id from (select student_id from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“002”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id /*分组条件:在上方查询条件的基础上,保证学习的课程总数相同*/ having count(score.corse_id)=(select count(corse_id) from score where student_id=1) order by student_id) a where (select count(corse_id) from score where student_id in()) >=(select count(corse_id) from score where student_id=1); select count(corse_id) from score group by student_id; --OK --查询至少学过学号为“001”同学所有课的其他同学学号和姓名; select student_id,count(corse_id) from score where student_id in(select student_id from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“001”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id /*分组条件:在上方查询条件的基础上,保证学习的课程总数相同*/ having count(score.corse_id)=(select count(corse_id) from score where student_id=1) order by student_id) group by student_id having count(corse_id) >= (select count(corse_id) from score where student_id=1); --ok --最终版 查询至少学过学号为“001”同学所有课的其他同学学号和姓名; -- 思路:先取出和01完全相同的 然后再统计一遍选课总数大于01所选总数; select student_id as '学生学号',student.sname as '学生姓名',count(corse_id) as '课程总数' /* 成绩表score 拼接 学生表student 用来取到:tudent.sname*/ from score left join student on score.student_id=student.sid where student_id in( select student_id from score left join student on score.student_id = student.sid where student_id in ( select student_id from score where student_id != 1 group by student_id HAVING count(corse_id) = (select count(1) from score where student_id = 1) ) and corse_id in (select corse_id from score where student_id = 1) group by student_id HAVING count(corse_id) = (select count(1) from score where student_id = 1) ) /* 对成绩表score 按照student_id分组*/ group by student_id having count(corse_id) >=(select count(corse_id) from score where student_id=1); select student_id as '学生学号',student.sname as '学生姓名',count(corse_id) as '课程总数' /* 成绩表score 拼接 学生表student 用来取到:tudent.sname*/ from score left join student on score.student_id=student.sid where student_id in( select student_id from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“001”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id /*分组条件:在上方查询条件的基础上,限定条件学习的课程总数相同,取到和学生1所选课程全部相同的学生ID*/ having count(score.corse_id)=(select count(corse_id) from score where student_id=1) ) /* 对成绩表score 按照student_id分组*/ group by student_id having count(corse_id) >=(select count(corse_id) from score where student_id=1); +--------------+--------------+--------------+ | 学生学号 | 学生姓名 | 课程总数 | +--------------+--------------+--------------+ | 8 | 刘德华 | 3 | | 14 | 李晨 | 4 | +--------------+--------------+--------------+ 2 rows in set (0.00 sec) select student_id as '学生学号',student.sname as '学生姓名',count(corse_id) as '课程总数' from score left join student on score.student_id=student.sid where student_id in( select student_id from score left join student on score.student_id=student.sid where score.corse_id in(select corse_id from score where student_id=1) and student_id!=1 group by student_id having count(score.corse_id)=(select count(corse_id) from score where student_id=1) ) group by student_id having count(corse_id) >=(select count(corse_id) from score where student_id=1);
14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名;
---思路: 先查询了解一下【学号为“002”的同学所学的课程】 select student_id as '学号',student.sname as '学生姓名',corse_id from score left join student on score.student_id=student.sid where student_id=2; +--------+--------------+----------+ | 学号 | 学生姓名 | corse_id | +--------+--------------+----------+ | 2 | 王小龙 | 2 | | 2 | 王小龙 | 3 | +--------+--------------+----------+ 2 rows in set (0.00 sec) --OK-按照12题的思路继续编写: select student_id as '学号',student.sname as '学生姓名' from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“002”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id /*分组条件:在上方查询条件的基础上,保证学习的课程总数相同*/ having count(score.corse_id)=(select count(corse_id) from score where student_id=1) order by student_id; select student_id as '学号',student.sname as '学生姓名',count(corse_id),count(student_id) from score left join student on score.student_id=student.sid /*查询条件:学生学习的课程在【学号为“002”的同学所学的课程科目】中*/ where score.corse_id in(select corse_id from score where student_id=1) /*排除自身,即不包括002同学自己*/ and student_id!=1 group by student_id having count(score.corse_id)=(select count(corse_id) from score where student_id=1) ---laoshi wangquanxiangtong de sulu select student_id,sname from score left join student on score.student_id = student.sid where student_id in ( /*查处学号不是1的学生 分组 */ select student_id from score where student_id != 1 group by student_id HAVING count(corse_id) = (select count(1) from score where student_id = 1) ) and corse_id in (select corse_id from score where student_id = 1) group by student_id HAVING count(corse_id) = (select count(1) from score where student_id = 1) --湘林 思路:------------------------------------------ select e.student_id,f.sname from ( select c.student_id from (select score.student_id,count(*) as count from score, (select * from score where student_id=2) b where score.course_id=b.course_id and score.student_id!=2 group by score.student_id ) c, (select count(*) as count from score where student_id=2) d where c.count=d.count) e left join student f on e.student_id = f.sid; SELECT sid AS student_id,sname FROM student WHERE sid IN ( SELECT student_id FROM score WHERE student_id IN ( SELECT student_id FROM score GROUP BY student_id HAVING count(student_id) = (SELECT COUNT(*) FROM score WHERE student_id = 2 ) AND student_id != 2 ) AND course_id IN (SELECT course_id FROM score WHERE student_id = 2) GROUP BY student_id HAVING COUNT(student_id) = (SELECT COUNT(*) FROM score WHERE student_id = 2 ) ); ------------------------------------------------------------ +--------+--------------+ | 学号 | 学生姓名 | +--------+--------------+ | 1 | 王小虎 | | 5 | 张小丽 | | 8 | 刘德华 | | 9 | 梁朝伟 | | 12 | 张曼玉 | | 14 | 李晨 | | 16 | 陈赫 | +--------+--------------+ 7 rows in set (0.00 sec)
15、删除学习“叶平”老师课的SC表记录;
select student_id as '学号',student.sname as '学生姓名',count(corse_id) from score left join student on score.student_id=student.sid where corse_id in(select corse_id from score where student_id=2) and student_id!=2 group by student_id order by student_id;
--16题之后 用的数据库是老师的:
16、向score表中插入一些记录,这些记录要求符合以下条件:
①没有上过编号“002”课程的同学学号;
②插入“002”号课程的平均成绩;
--条件1 思路:先查出没有上过课程编号为'2'的学生学号 select student_id from score where student_id not in( select student_id from score where course_id='2') group by student_id; +------------+ | student_id | +------------+ | 2 | | 13 | +------------+ 2 rows in set (0.00 sec) --再计算出课程‘2’的平均成绩 select avg(num) from score group by course_id having course_id=2; --最后
17、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
--思路: 用到的知识:1 字段子查询 2 自连接 --字段子查询 select (select caption from class where cid=1),'生物',sid,num from score; --OK 自连接 select student_id as '学号', (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=1) as '生物', (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=2) as '物理', (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=3) as '体育', count(student_id) as '有效课程总数', /*根据OuterTb.student_id分组后 计算平均成绩 可以替换成:sum(num)/count(student_id)*/ /*注意这里求出的平均分是所有科目的平均分 */ avg(num) as '有效平均分(升序)' from score as OuterTb group by OuterTb.student_id order by avg(num) asc; ---求 生物 物理 体育的平均分数 select student_id as '学号', (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=1) as sw, (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=2) as wl, (select num from score as Inner_Tb where Inner_Tb.student_id=OuterTb.student_id and course_id=3) as ty, count(student_id) as '有效课程总数', sw.num+wl.num+ty.num from score as OuterTb group by OuterTb.student_id order by avg(num) asc; --横向求和 select isnull([津贴],0)+isnull([补贴],0) as hj from gongzi where id=10 -- 方法二 行转列
18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
select student_id as '学号',student.sname as '学生姓名',count(corse_id) from score left join student on score.student_id=student.sid where corse_id in(select corse_id from score where student_id=2) and student_id!=2 group by student_id order by student_id;
19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;
--思路 先查询各科的平均成绩 升序 select course_id,avg(num) from score left join course on score.course_id=course.cid group by course_id order by avg(num); 在查询各科的及格率 降序 select course_id, sum(case when score.num>60 then 1 else 0 END)/count(course_id)*100 as percent from score left join course on score.course_id=course.cid group by course_id order by percent desc; -- 然后把上述两步合并 --老师思路 select course_id, avg(num) as avgnum, sum(case when score.num > 60 then 1 else 0 END)/count(1)*100 as percent from score group by course_id order by avgnum asc,percent desc;
20、课程平均分从高到低显示(显示任课老师);
--思路:先查出课程平均分 然后降序排列 (调用19题 思路1) select course_id,avg(num) from score left join course on score.course_id=course.cid group by course_id order by avg(num) desc; --然后,显示任课老师 说明要让成绩表关联课程表 score.course_id=course.cid --同时课程表关联老师表 course.teacher_id=teacher.tid select course_id as '课程编号',teacher.tname as '任课教师',avg(num) as '课程平均分' from score left join (course,teacher) on score.course_id=course.cid and course.teacher_id=teacher.tid group by course_id order by avg(num) desc; +--------------+-----------------+-----------------+ | 课程编号 | 任课教师 | 课程平均分 | +--------------+-----------------+-----------------+ | 4 | 李平老师 | 85.2500 | | 2 | 李平老师 | 65.0909 | | 3 | 刘海燕老师 | 64.4167 | | 1 | 张磊老师 | 53.4167 | +--------------+-----------------+-----------------+ 4 rows in set (0.00 sec) --20题 --老师思路: --存在问题 主表不应该是course 而应该是score select avg(if(isnull(score.num),0,score.num)),teacher.tname from course left join score on course.cid=score.course_id left join teacher on course.teacher_id=teacher.tid group by score.course_id; --正确写法: select avg(if(isnull(score.num),0,score.num)),teacher.tname from score left join course on score.course_id=course.cid left join teacher on course.teacher_id=teacher.tid group by course_id order by avg(if(isnull(score.num),0,score.num)) desc;
21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
--思路:先查出 所有学生生物成绩 然后按照成绩升序 后排序 最后分页limit 3 select * from score where course_id =1 order by num desc limit 3; select * from score where course_id =2 order by num desc limit 3; select * from score where course_id =3 order by num desc limit 3; ... ---产生笛卡尔集的方式 select * from (select student_id,course_id,num from score where course_id =1 order by num desc limit 3) as A, (select student_id,course_id,num from score where course_id =2 order by num desc limit 3) as B, (select student_id,course_id,num from score where course_id =3 order by num desc limit 3) as C --union 连表方式: select * from (select student_id,course_id,num from score where course_id =1 order by num desc limit 3) as A union select * from (select student_id,course_id,num from score where course_id =2 order by num desc limit 3) as B union select * from (select student_id,course_id,num from score where course_id =3 order by num desc limit 3) as C; +------------+-----------+-----+ | student_id | course_id | num | +------------+-----------+-----+ | 9 | 1 | 91 | | 11 | 1 | 90 | | 10 | 1 | 90 | | 6 | 2 | 100 | | 8 | 2 | 100 | | 7 | 2 | 100 | | 3 | 3 | 87 | | 13 | 3 | 87 | | 2 | 3 | 68 | +------------+-----------+-----+ 9 rows in set (0.00 sec) --思路二 取出各科成绩的第一名 再取出第二名 。。。 select score.course_id,course.cname,max(num) as '第一名' from score left join course on score.course_id=course.cid group by course_id; +-----------+--------+-----------+ | course_id | cname | 第一名 | +-----------+--------+-----------+ | 1 | 生物 | 91 | | 2 | 物理 | 100 | | 3 | 体育 | 87 | | 4 | 美术 | 100 | +-----------+--------+-----------+ 4 rows in set (0.00 sec) select num from score where course_id =1 order by num desc limit 1 offset 1; select num from score where course_id =1 order by num desc limit 1 offset 1; select * from (select score.course_id,course.cname,max(num) as '第一名' from score left join course on score.course_id=course.cid group by course_id) as A; select sid, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num from score as s1 group by first_num select sid, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num from score as s1 -- +-----+-----------+-----+-----------+------------+ | sid | course_id | num | first_num | second_num | +-----+-----------+-----+-----------+------------+ | 34 | 1 | 91 | 91 | 90 | | 38 | 1 | 90 | 91 | 90 | | 42 | 1 | 90 | 91 | 90 | | 46 | 1 | 90 | 91 | 90 | | 23 | 2 | 100 | 100 | 88 | | 27 | 2 | 100 | 100 | 88 | | 31 | 2 | 100 | 100 | 88 | select course_id from score group by course_id; select student_id from score group by student_id; ----课上
22、查询每门课程被选修的学生数;
select course_id, count(course_id) from score group by course_id;
23、查询出只选修了一门课程的全部学生的学号和姓名;
--老师的错误 select student.sid, student.sname, count(1) from score left join student on score.student_id=student.sid group by course_id having count(1)=1 --正确应该 以学生ID分组 select student.sid, student.sname, count(1) from score left join student on score.student_id=student.sid group by score.student_id having count(1)=1
24、查询男生、女生的人数;
select * from (select count(1) as man from student where gender='男') as A , (select count(1) as feman from student where gender='女') as B
25、查询姓“张”的学生名单;
select sname from student where sname like '张%';
26、查询同名同姓学生名单,并统计同名人数;
--老师的少一个条件 count(1)>1 select sname,count(1) as count from student group by sname having count(1)>1;
27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
select course_id,avg(if(isnull(num), 0 ,num)) as avg from score group by course_id order by avg asc,course_id desc;
28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
select student_id,sname, avg(if(isnull(num), 0 ,num)) from score left join student on score.student_id = student.sid group by student_id;
29、查询课程名称为“生物”,且分数低于60的学生姓名和分数;
select student.sname,score.num from score left join course on score.course_id = course.cid left join student on score.student_id = student.sid where score.num < 60 and course.cname = '生物';
30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
select * from score where score.student_id = 3 and score.num > 80
31、求选了课程的学生人数
select count(distinct student_id) from score;
32、查询选修“李平”老师所授课程的学生中,成绩最高的学生姓名及其成绩;
33、查询各个课程及相应的选修人数;
select course.cname,count(1) from score
left join course on score.course_id = course.cid
group by course_id;
34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
select DISTINCT s1.course_id,s2.course_id,s1.num,s2.num
from score as s1, score as s2
where s1.num = s2.num and s1.course_id != s2.course_id;
+-----------+-----------+-----+-----+
| course_id | course_id | num | num |
+-----------+-----------+-----+-----+
| 1 | 2 | 9 | 9 |
| 2 | 4 | 66 | 66 |
| 2 | 1 | 77 | 77 |
| 4 | 2 | 66 | 66 |
| 4 | 3 | 87 | 87 |
| 2 | 4 | 100 | 100 |
| 2 | 1 | 9 | 9 |
| 4 | 2 | 100 | 100 |
| 2 | 4 | 88 | 88 |
| 4 | 2 | 88 | 88 |
| 1 | 2 | 77 | 77 |
| 3 | 4 | 87 | 87 |
+-----------+-----------+-----+-----+
12 rows in set (0.00 sec)
select DISTINCT s1.student_id,s2.student_id,s1.course_id,s2.course_id,s1.num,s2.num
from score as s1, score as s2
where s1.num = s2.num and s1.course_id != s2.course_id;
35、查询每门课程成绩最好的前两名;
--先查处李平老师所教的课程 select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师'; +-----+ | cid | +-----+ | 2 | | 4 | +-----+ 2 rows in set (0.00 sec) ----再取出李平老师 所授课程的学生中 课程名称和最高成绩 select course_id,max(num) from score left join student on score.student_id = student.sid group by course_id having course_id in(select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师'); +-----------+----------+ | course_id | max(num) | +-----------+----------+ | 2 | 100 | | 4 | 100 | +-----------+----------+ 2 rows in set (0.00 sec) --最后拼接学生表 分数对应到学生姓名 select course_id,num from score where course_id in (select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师') order by course_id asc,num desc select course_id,max(num) from score where course_id in (select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师') group by course_id; select student_id from score as Inner_Tb where Inner_Tb.course_id=OuterTb.course_id and select course_id,max(num), (select student_id from score as Inner_Tb where Inner_Tb.course_id=OuterTb.course_id group by student_id having student_id) from score as OuterTb where course_id in (select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师') group by course_id; select course_id,max(num), (select student_id from score as Inner_Tb where Inner_Tb.course_id=OuterTb.course_id where ) as '学号' from score as OuterTb where course_id in (select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='李平老师') group by course_id; sid | student_id | course_id | num | update score set num=99 where sid=17; mysql> select max(num) from score where course_id=2 or course_id=4; +----------+ | max(num) | +----------+ | 100 | +----------+ 1 row in set (0.00 sec) ----32题另一种思路:查询选修“李平”老师所授课程的学生中,成绩最高的学生姓名及其成绩 ----考虑到并列第一的情况 select t1.sname as '学生姓名',t3.cname as '课程名称',t2.num as '该课程最高成绩',t4.tname as '授课教师' from student t1, score t2,course t3,teacher t4 where t1.sid = t2.student_id and t2.course_id = t3.cid and t3.teacher_id = t4.tid and t4.tname = '李平老师' and t2.num = (select max(num) from score where course_id=t3.cid ); +--------------+--------------+-----------------------+--------------+ | 学生姓名 | 课程名称 | 该课程最高成绩 | 授课教师 | +--------------+--------------+-----------------------+--------------+ | 张四 | 物理 | 100 | 李平老师 | | 铁锤 | 物理 | 100 | 李平老师 | | 张四 | 美术 | 100 | 李平老师 | +--------------+--------------+-----------------------+--------------+ 3 rows in set (0.00 sec) select a.* from score a where course_id=(select max(num) from score where course_id=a.course_id limit 1); select t1.sname as '学生姓名',t3.cname as '课程名称',t2.num as '该课程最高成绩',t4.tname as '授课教师' from student t1, score t2,course t3,teacher t4 where t1.sid = t2.student_id and t2.course_id = t3.cid and t3.teacher_id = t4.tid and t4.tname = '李平老师' and t2.num = (select max(num) from score where course_id=t3.cid ); --老师 思路 有问题 select student.sname,num 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 tname='李平老师') order by num desc limit 1;
36、检索至少选修两门课程的学生学号;
37、查询全部学生都选修的课程的课程号和课程名;
select course_id,count(1) from score group by course_id having count(1) = (select count(1) from student);
38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;
39、查询两门以上不及格课程的同学的学号及其平均成绩;
select student_id,count(1) from score where num < 60 group by student_id having count(1) > 2
40、检索“004”课程分数小于60,按分数降序排列的同学学号;
select student_id from score where num< 60 and course_id = 4 order by num desc;
41、删除“002”同学的“001”课程的成绩;
delete from score where course_id = 1 and student_id = 2