[声响] 查询可以嵌套 嵌入到另一个查询中的查询称为子查询
启动企业管理器,登陆数据库服务器
新建查询,要执行 USE teaching
选用 teaching 为当前数据库
这次呢,我们使用三个表,一个叫做 Student2
,一个叫做成绩表 score 一个叫课程表 course。
我们先来浏览一下这三个数据表里的数据
这是学生表,里面有 班级、
学号、 姓名、 性别、 出生日期 年龄和籍贯。
这是成绩表,里面是 学号、
课程编号和成绩 这是课程表,里面有
课程编号、 课程名称、 学时、
学分和简介 我们下来看第一个例子
是说,查询班级人数不足 5
人的班级中 学生的学号、 姓名和班级。
那么班级人数 不足 5
人的班级,我们先考虑这个问题,班级人数不足 5 人 的班级。
我们可以这样写这个查询语句: SELECT
班级 sclass FROM student2
,按照班级呢来进行分组,然后呢看 哪一个这个记录的数小于
5 ,这就是班级 人数不足 5 人的班级。
所以呢 不足 5 人的班级有电气 61 和英语两个班
这个出来以后呢,我们要看学生表里头的 那么哪个是电气
61 的这些学生要列出来,英语的学生要列出来,所以呢,那么这个 结果呢应该是我们的选择条件。
这个时候呢我们可以这样来写这个查询语句 SELECT,这是学号、
姓名和 班级, FROM student2 这个表当中, WHERE
就是我们的班级 要在刚才的这个查询结果里面,是刚才的
查询结果之一,所以这个时候呢,我们这个 WHERE 条件是 WHERE sclass
IN 后面一对圆括号,这里头呢就可以写刚才的这个查询
也就是说这个查询 结果是作为我们这个
IN 这个括号里头呢那个集合里头的 数据。
好,下来我们来执行这个语句,我们就得到了 这是电气
61 班的学生,这是英语班的学生
这个里面 IN 后面括号里头的这个 SELECT
什么什么什么东西 就是一个子查询。
多数的子查询 可以通过多表连接查询来得到,但是呢使用子查询
逻辑上显得更加清楚。
下来我们看第二个例子 是说如果"物理"班有人的成绩
大于等于 90 ,那么就把这个班里头的 学号、
姓名、 班级、 课程号和成绩呢显示出来。
我们也是先考虑这 里头的第一个问题,就是"物理"班有人的成绩大于等于
90,我们先来 看这个语句怎么找,也就这个信息来怎么找
"物理"班有人的成绩大于等于 90 ,我们就可以查询"物理"班成绩大于等于
90 的学生信息,如果能找到就是有,找不到就是没有。
我们可以写 SELECT * FROM student2
, 因为是成绩大于等于 90
,那么成绩呢是在成绩表里头的 所以我们要把学生表跟成绩表用内连接
连接起来,连接条件是学生表里头的学号 和课程表里头的学号要相等。
那我们的筛选条件呢,是班级要是物理,并且呢 分数呢大于等于 90。
我们执行这一句 这就是"物理"班当中成绩大于 90 的 那些学生的信息。
好了,这个有的话,我们要把全班人的信息呢显示出来
我们这样来写这个查询语句 SELECT
班级、 学号、 姓名、 课程编号和成绩, FROM
student2 ,然后呢和 成绩表呢连接起来,连接条件是学生
表里头的学号和成绩表里头的学号相等。
筛选条件是 班级等于物理,并且呢这个班里头应该有人的成绩是大于等于
90 的 所以我们就写了一个 AND EXISTS ,
后面是那个 有没有人大于等于 90 分,那么刚才有没有人呢,我们用的是
这个查询语句,我们就把这个查询语句呢放到这个 EXISTS
后面这个括号里头,那么就是说 这就是一个子查询,如果这个查询能够得到
那么就是存在的,我们就能够显示出"物理"班的 学生的信息来。
这就是 "物理"班的学生信息,它们班是有人的成绩大于等于
90 的 相反,比方说我们把这个"物理"班改成"航天"班
好,我们执行这一段,执行这个子查询,这就是说,"航天"班 大于等于 90 的那些同学是谁。
这样查了以后呢,这里头是没有记录的,也就是说 "航天"班里头的学生的成绩没有一个
是大于等于 90 的,这样子呢
我们在执行这个语句的时候呢,由于没有人大于等于 90
所以这个 EXISTS 呢实际上是不成立的,它是 false 的 所以 WHERE
后面这个条件呢也是不成立的,所以最后呢我们这个结果呢,查询 出来也是空,也是空。
所以这就是 EXISTS 括号里头这就是一个子查询
第三个例子,是显示
航天班成绩在平均成绩以上的人的 班级、
学号、 姓名、 课程编号和成绩。
所以我们首先要知道平均成绩是多少 那么,所有人的所有课程的平均成绩
我们可以使用这个查询语句: SELECT AVG 对成绩求平均,
FROM 成绩表,这就是 平均成绩。
平均成绩以上的这些人呢,我们可以写 SELECT
班级、 学号、 姓名、 课程号和分数,然后
FROM 学生表 as a , a 是它的别名。
INNER JOIN 是做一个内连接 和这个成绩表做一个内连接,然后
b 是成绩表的别名,连接条件是
学生表里头的学号跟成绩表里头的学号要相等。
条件呢是成绩表里头的分数
要大于什么东西呢?要大于平均成绩,大于平均成绩,所以呢这就是我们的刚才查到的 平均成绩。
这个 ANY 呢就是说它是这个集合里 头的任何一个都可以。
我们来执行这一句 这就是所有的成绩大于平均成绩的那些人
刚才我们还有个条件呢,是说要是航天班的,我们在这个 WHERE
后面呢再加一个条件 它的成绩呢要大于平均成绩,并且呢班级,班级呢要等于 航天。
所以呢这再查出来的话,就是航天班里头 成绩在平均成绩以上的那些人的信息。
ANY 后面这个括号里头的这个 SELECT 就是 子查询。
下来我们看第四个例子,查询
学生的班级数,查询学生的班级数
我们先把这个问题简化一下,查询呢学生来自于 哪些班级。
我们可以写 SELECT distinct sclass
,就是班级, FROM student2 , distinct 呢就是去掉 重复的行。
这样呢我们就查出了这些学生他的班级 是电气、 航天、
物理、 信计和英语 那我们最终的目标呢是要得到这个班级的数量是
5 ,那么也就是说呢我们可以在这个基础
之上来统计一下班级的数量 班级的数量,所以呢这个查询的结果应该像是
我们统计的数据源,那么我们可以把这个结果呢放到哪去呢?这次不是放到 WHERE
这个 条件里头去了,而是放到 FROM
后面是,原来我们是表的列表,这个地方呢 我们也可以放一个子查询。
所以呢,这个语句 我们就写: SELECT count(*)
AS 班级数, FROM 后面加一个圆括号,这里头就写了
刚才我们的查询语句,这个查询语句,这个子查询 查到的是哪些班级,哪些班级
然后我们从这个班级里头呢再统计出有多少个,后面呢要注意要写一个 AS
a 那就是说给这个查询的结果起一个别名。
我们来执行这一句,我们看到的就是 班级数 5。
所以呢,这个题目呢
就是相当于是在这个查询的结果之上再进行查询,将查询结果看做一个
新的表来进行查询的。
另外呢,子查询 还可以再嵌套子查询,不过查询语句就会显得更加的复杂。
如果要使用 逻辑上一定要梳理清楚。
关于子查询我们就讲到这
[空白音频]