一、分组计算平均成绩
查询每门课的平均成绩(分组查询,group by)
---只查询3-105号课程
select avg(degree) from score where cno='3-105';
+-------------+
| avg(degree) |
+-------------+
| 85.3333 |
+-------------+
---分组查询
select cno,avg(degree) from score group by cno;
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 85.3333 |
| 3-245 | 76.333/3 |
| 6-166 | 81.66/67 |
+-------+-------------+
二、分组条件与模糊查询
查询score表中至少有2名学生选修的,并且以3开头的课程的平均分。
- HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。
HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足。 - 模糊查询 LIKE
%代表一个或多个字符的通配符,_代表仅仅一个字符的通配符
select cno,avg(degree) from score group by cno having count(cno)>=2 and cno like '3%';
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 85.3333 |
| 3-245 | 76.3333 |
+-------+-------------+
三、多表查询
使用共同字段匹配
查询所有的学生 sname(student) , cno(score), degree(score)列
select sname,cno,degree from student,score where student.sno=score.sno;
+-----------+-------+--------+
| sname | cno | degree |
+-----------+-------+--------+
| 王丽 | 3-105 | 92 |
| 王丽 | 3-245 | 86 |
| 王丽 | 6-166 | 85 |
| 王芳 | 3-105 | 88 |
| 王芳 | 3-245 | 75 |
| 王芳 | 6-166 | 79 |
| 赵铁柱 | 3-105 | 76 |
| 赵铁柱 | 3-245 | 68 |
| 赵铁柱 | 6-166 | 81 |
+-----------+-------+--------+
查询所有学生的sno(score), cname(course), degree(score)列
select sno,cname,degree from score,course where score.cno=course.cno;
+-----+-----------------+--------+
| sno | cname | degree |
+-----+-----------------+--------+
| 103 | 计算机导论 | 92 |
| 105 | 计算机导论 | 88 |
| 109 | 计算机导论 | 76 |
| 103 | 操作系统 | 86 |
| 105 | 操作系统 | 75 |
| 109 | 操作系统 | 68 |
| 103 | 数字电路 | 85 |
| 105 | 数字电路 | 79 |
| 109 | 数字电路 | 81 |
+-----+-----------------+--------+
.查询所有的学生 sname (student), cname(course), degree(score)列
score表作为关联起student和course的表
select sname,cname,degree from student,course,score
where student.sno=score.sno and course.cno=score.cno;
+-----------+-----------------+--------+
| sname | cname | degree |
+-----------+-----------------+--------+
| 王丽 | 计算机导论 | 92 |
| 王丽 | 操作系统 | 86 |
| 王丽 | 数字电路 | 85 |
| 王芳 | 计算机导论 | 88 |
| 王芳 | 操作系统 | 75 |
| 王芳 | 数字电路 | 79 |
| 赵铁柱 | 计算机导论 | 76 |
| 赵铁柱 | 操作系统 | 68 |
| 赵铁柱 | 数字电路 | 81 |
+-----------+-----------------+--------+
四、子查询
子查询就是指的在一个完整的查询语句之中,嵌套若干个不同功能的小查询,从而一起完成复杂查询的一种编写形式。
查询班级是’95031’班学生每门课的平均分
---先查询95031所有的学生
select * from student where class='95031';
---查询95031班所有学生的成绩
select * from score where sno in (select sno from student where class='95031');
---最后按照cno分组来求平均成绩
select cno,avg(degree) from score
where sno in (select sno from student where class='95031')
group by cno;
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 82.0000 |
| 3-245 | 71.5000 |
| 6-166 | 80.0000 |
+-------+-------------+
查询成绩高于学号为’109’,课程号为’3-105’的成绩的所有记录
---先找到109号同学3-105的成绩
select degree from score where sno='109' and cno='3-105';
---再找到成绩高于他的所有记录
select * from score where degree>(select degree from score where sno='109' and cno='3-105');
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
| 105 | 6-166 | 79 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
查询选修"3-105"课程的成绩高于’109’号同学’3-105’成绩 的所有同学的记录
---先找到109号同学3-105的成绩
select degree from score where sno='109' and cno='3-105';
---再找到成绩高于他的所有选修3-105同学记录
select * from score where cno='3-105' and degree>(select degree from score where sno='109' and cno='3-105');
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 105 | 3-105 | 88 |
+-----+-------+--------+
查询所有和学号为108、101的同学同年出生的所有学生的sno,sname和sbirthday
---查出这两位同学的出生年份
select year(sbirthday) from student where sno in(108,101);
---查询所有出生年份和他们相同的学生信息
select sno,sname,sbirthday from student
where year(sbirthday) in (select year(sbirthday) from student where sno in(108,101));
+-----+-----------+---------------------+
| sno | sname | sbirthday |
+-----+-----------+---------------------+
| 101 | 曾华 | 1977-09-01 00:00:00 |
| 102 | 匡明 | 1975-10-02 00:00:00 |
| 105 | 王芳 | 1975-02-10 00:00:00 |
| 108 | 张全蛋 | 1975-02-10 00:00:00 |
+-----+-----------+---------------------+
---
查询 张旭 教师任课的学生的成绩(多层嵌套子查询)
---查询“张旭”的教师编号
select tno from teacher where tname='张旭';
---根据教师编号到course表中查询教学课程的课程号
select cno from course where tno=(select tno from teacher where tname='张旭');
---根据课程号到score表中查询学生的成绩
select * from score where cno=(select cno from course where tno=(select tno from teacher where tname='张旭'));
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 6-166 | 85 |
| 105 | 6-166 | 79 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
查询选修课程的同学人数多于 5 人的教师姓名(多表子查询)
---先找到选修人数大于5的课程号
select cno from score group by cno having count(*)>5;
---通过课程号找到教师编号
select tno from course where cno in (select cno from score group by cno having count(*)>5);
--最后通过教师编号找到教师姓名
select tname from teacher where tno in (select tno from course where cno in (select cno from score group by cno having count(*)>5));
+--------+
| tname |
+--------+
| 王萍 |
+--------+
查出所有’计算机系’ 教师所教课程的成绩表
---找到计算机系教师的教师编号
select tno from teacher where depart='计算机系';
---根据编号找到所教课程课程号
select cno from course where tno in (select tno from teacher where depart='计算机系');
---根据课程号找到成绩表
select * from score where cno in (select cno from course where tno in (select tno from teacher where depart='计算机系'));
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-245 | 86 |
| 105 | 3-245 | 75 |
| 109 | 3-245 | 68 |
| 101 | 3-105 | 90 |
| 102 | 3-105 | 91 |
| 103 | 3-105 | 92 |
| 104 | 3-105 | 89 |
| 105 | 3-105 | 88 |
| 109 | 3-105 | 76 |
+-----+-------+--------+
五、in表示或者关系
查询95033班和95031班全体学生的记录
select * from student where class in('95033','95031');
+-----+-----------+------+---------------------+-------+
| sno | sname | ssex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
六、union和not in的使用
union表示并集,not in表示不存在于
查询**‘计算机系’与’电子工程系’** 不同职称的教师的姓名和职称
---先查计算机系老师职称
select prof from teacher where depart='计算机系';
---同样求电子工程系
select prof from teacher where depart='电子工程系';
---计算机系老师的职称不在电子工程系中的姓名和职称
select tname,prof from teacher where depart='计算机系' and prof not in (select prof from teacher where depart='电子工程系');
+--------+-----------+
| tname | prof |
+--------+-----------+
| 李诚 | 副教授 |
+--------+-----------+
---电子工程系老师的职称不在计算机系中的姓名和职称
select tname,prof from teacher where depart='电子工程系' and prof not in (select prof from teacher where depart='计算机系');
+--------+--------+
| tname | prof |
+--------+--------+
| 张旭 | 讲师 |
+--------+--------+
---最后使用union拼接
select tname,prof from teacher
where depart='计算机系'
and prof not in (select prof from teacher where depart='电子工程系')
union
select tname,prof from teacher
where depart='电子工程系'
and prof not in (select prof from teacher where depart='计算机系');
+--------+-----------+
| tname | prof |
+--------+-----------+
| 李诚 | 副教授 |
| 张旭 | 讲师 |
+--------+-----------+
七、any表示任意
查询选修编号为"3-105"课程且成绩至少高于选修编号为’3-245’同学的cno,sno和degree,并且按照degree从高到地次序排序。
题干中至少的意思为,大于其中任意一个即可。
---先查询选修号为3-245的所有成绩
select degree from score where cno='3-245';
---再找选修3-105中至少比它高的成绩及对应的cno、sno
select cno,sno,degree from score where cno='3-105' and degree>any(select degree from score where cno='3-245') order by degree desc;
+-------+-----+--------+
| cno | sno | degree |
+-------+-----+--------+
| 3-105 | 103 | 92 |
| 3-105 | 102 | 91 |
| 3-105 | 101 | 90 |
| 3-105 | 104 | 89 |
| 3-105 | 105 | 88 |
| 3-105 | 109 | 76 |
+-------+-----+--------+
八、all表示所有
查询选修编号为"3-105"且成绩高于选修编号为"3-245"课程的同学cno、sno和degree。
和上个题类似,区别在于不再是任意,而是高于3-245所有成绩。
--将上题中的any改为all即可
select cno,sno,degree from score where cno='3-105' and degree>all(select degree from score where cno='3-245');
+-------+-----+--------+
| cno | sno | degree |
+-------+-----+--------+
| 3-105 | 101 | 90 |
| 3-105 | 102 | 91 |
| 3-105 | 103 | 92 |
| 3-105 | 104 | 89 |
| 3-105 | 105 | 88 |
+-------+-----+--------+
九、as取别名
查询所有教师和同学的 name ,sex, birthday
教师和同学的字段名不同,所以需要使用as将它们都重命名为相同字段名,使用union拼接,后半段的字段名依赖于前半段。
select tname as name,tsex as sex,tbirthday as birthday from teacher
union
select sname,ssex,sbirthday from student;
+-----------+-----+---------------------+
| name | sex | birthday |
+-----------+-----+---------------------+
| 李诚 | 男 | 1958-12-02 00:00:00 |
| 王萍 | 女 | 1972-05-05 00:00:00 |
| 刘冰 | 女 | 1977-08-14 00:00:00 |
| 张旭 | 男 | 1969-03-12 00:00:00 |
| 曾华 | 男 | 1977-09-01 00:00:00 |
| 匡明 | 男 | 1975-10-02 00:00:00 |
| 王丽 | 女 | 1976-01-23 00:00:00 |
| 李军 | 男 | 1976-02-20 00:00:00 |
| 王芳 | 女 | 1975-02-10 00:00:00 |
| 陆军 | 男 | 1974-06-03 00:00:00 |
| 王尼玛 | 男 | 1976-02-20 00:00:00 |
| 张全蛋 | 男 | 1975-02-10 00:00:00 |
| 赵铁柱 | 男 | 1974-06-03 00:00:00 |
| 张飞 | 男 | 1974-06-03 00:00:00 |
+-----------+-----+---------------------+
查询所有’女’教师和’女’学生的name,sex,birthday
---上题稍加修改即可
select tname as name,tsex as sex,tbirthday as birthday from teacher where tsex='女'
union
select sname,ssex,sbirthday from student where ssex='女';
+--------+-----+---------------------+
| name | sex | birthday |
+--------+-----+---------------------+
| 王萍 | 女 | 1972-05-05 00:00:00 |
| 刘冰 | 女 | 1977-08-14 00:00:00 |
| 王丽 | 女 | 1976-01-23 00:00:00 |
| 王芳 | 女 | 1975-02-10 00:00:00 |
+--------+-----+---------------------+
十、复制表数据做条件查询
查询成绩比该课程平均成绩低的同学的成绩表
复制一份score表,从a表中遍历成绩比对b表中查到的平均成绩
select * from score a where degree<(select avg(degree) from score b where a.cno=b.cno);
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
---一份平均成绩做参照
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 87.6667 |
| 3-245 | 76.3333 |
| 6-166 | 81.6667 |
+-------+-------------+