MySQL——查询练习(2)

一、分组计算平均成绩

查询每门课的平均成绩(分组查询,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 |
+-------+-------------+
发布了60 篇原创文章 · 获赞 6 · 访问量 1205

猜你喜欢

转载自blog.csdn.net/DLC990319/article/details/105063824