前面我们查询数据
数据都来源于一张数据表,如果我们想查询
某一同学《数据库技术》这门课程得了多少分 那这些信息分布在多张数据表中,查询时
需要涉及学生表、 选课表和课程表 也就是说信息来源于多张数据表
这就是多表查询,下面我们来看 怎么做。
多表查询的最简单的格式是 SELECT*
或者是字段列表,FROM 数据表列表,就是这个地方呢可以是
多个数据表,中间呢用逗号隔开。
设我们有两个数据表,一个呢 叫做成绩表,里头是学号
课程号和分数。
另一个呢 是学生表,其中有学号、
名字和性别,那么 简单的多表查询呢,语句可以写成
SELECT* FROM 成绩表,逗号,学生表。
我们先看一下这个查询结果
这一次呢我们要用到三个表,一个就是 stu1
是学生表,一个呢是 course,是课程表 一个呢是 score,是成绩表。
我们先来浏览一下这三个表中的数据是什么样子的 这是学生表,里头有学号、
名字和性别 这里头呢有三位同学,这个呢是课程表
这是课程编号、 课程名称、 学时、 学分跟简介
这个呢是成绩表,这一列呢是学号,这是呢课程编号,后面是 分数。
我们先来看一下 这个最简单的多表查询,SELECT*
FROM score,stu1,就是从
成绩表跟学生表里头来查询信息 执行。
这是我们得到的 查询结果。
那这个查询结果
是怎么来的呢?这是我们的成绩表,这是我们的学生表,那就是
成绩表里头的第一行和学生表里头的第一行构成一条记录,成绩表里头的
第一行和学生表里头的第二行又构成 一条记录,成绩表里头的第一行和学生表里头的
第三行又构成了一条记录。
这样的话成绩表有两条记录,学生表有三条 记录,2
乘 3 就构成了 6 条记录。
基本结果呢 就是这样子的。
这样的结果呢我们称为笛卡尔乘积 那么它在查询的时候呢是没有加任何条件的
所以呢这种查询呢我们也叫做无条件的连接 无连接规则的连接,或者简称是无规则连接。
那么这样得到这样一个结果呢实际上是有一点 问题的。
就是这里头的很多很多的记录呢,逻辑上是错误的,或者是没有意义的 比方说这边是
001 号同学、 课程号、 成绩,那这边呢 对应成了
002 号同学了,所以这个对应关系呢,这条记录呢就是没有意义的
那么这个表里头呢只有这一条记录是有意义的,这一条记录呢是有意义的,所以我们在
查询的时候呢,就要加上连接的条件 比方说,我们查询的时候
可以说 SELECT* FROM score,stu1
加一个条件 WHERE score.numb = stu1.numb。
前头这两行呢 就是刚才的笛卡尔乘积,加上一个条件的时候呢,就把学号相等的
那些行,学号相等的那一行筛选出来的,所以这就是呢等值连接 注意呢,这里头呢,我们在这两个
numb 前头呢,一个是加了 score,一个加了呢 stu1,这表明前头这个 numb
是 score 里头的numb,后头的这个 numb 呢 是 stu1 里头的 numb。
因为如果我们不加的话,那就分不清 是哪个表里头的
numb,所以呢,就是当有相同字段的时候,我们要加上表的名字点
那等值连接呢就是在刚才的笛卡尔乘积的基础上
加上一个筛选条件,就是成绩表里头的学号跟学生表里头的学号相等的
我们把它呢筛选出来,所以剩下的这些记录呢就是有意义的
记录了,就是 1 号同学,课程
1 分数是多少,这个人的名字叫王宁,性别是女。
1 号同学 课程 2 分数、 王宁,1 号同学、 课程 3,2
号同学、 课程 1 还可以建立三个表的等值连接
多个表之间的等值连接,前头这个呢也是一个
笛卡尔乘积,实际上是三个表的笛卡尔乘积,我们也可以执行一下这个结果呢看一看
那么这个记录数呢也是很多了,相当于这个是 M N K
条记录的话,笛卡尔乘积的结果呢,行数就是 M 乘 N 乘 K 条记录
后面呢就是加上一个筛选条件,筛选条件 就是成绩表里头的学号跟学生表里头的学号要相等
成绩表里头的课程号跟课程表里头的课程号要相等,像这个以后那我们这个
结果就有意义了。
这就是哪位同学哪门课程成绩是多少
这边呢,从学生表里头能查到这个是谁,从课程表里头能查到这个课程名称 是什么。
这就是多个表之间的等值连接 我们还可以给它呢
加上条件,这样查到呢就是只有王宁的记录了,王宁的记录
我们也可以给它呢排序 那么我们对查询结果里头
按照课程名称排序,然后按照呢分数来排序,我们也可以呢
再让它降序 这个顺序呢就变了
刚才的查询
多次使用了表的名字,如果表名很长,写起来呢就比较费事
简化的方法就是给表呢起一个别名
然后使用别名呢就比较简单,一般的使用格式是,就是在 FROM
子句后面,表名 1 写一个 AS 别名
1,表名 2 AS 别名 2,表名 3 AS
别名 3, 等等 以后呢在 WHERE 子句当中需要表名的时候
就可以使用别名。
在表中呢使用别名 我们可以在这个,上面这个查询的基础上来改一下,FROM
score 后面加一个 as,我们写一个 a,a
就是这个成绩表的别名 后头呢我们这个地方呢写一个
as b,b 呢就是 stu1 的学生表的这个别名
course 后面加一个 course c,c 呢就是课程表的别名。
后面呢我们就把凡是 score 的地方 都写成 a,凡是
stu1 的地方都写成 b [空白音频]
都写成 b 啊,凡是 course 的地方呢 都写成
c,我们再来执行这一句,这个结果呢是一样的 这个结果呢是一样的。
那我们在写这一条查询语句的话呢,用 a,b,c
来讲的话就会 少敲好多字符,就显然呢更加快捷。
这就是使用表的 别名。
前后呢我们 查询的时候呢,使用了这个
SELECT*,如果我们要去掉重复列的时候呢,我们就不能用 SELECT*
了,我们就需要把我们需要看到的列 都列出来,比方说我们要查询的时候,我们要看到学号
姓名、 课程名和分数,那么我们
不写 * 了,我们写什么东西呢?学号,stu 1 里头的学号
姓名、 stu 1 里头的
name,然后还有呢,课程名,那就是课程里头的 c
点 课程名,stu 1 可以改成、 改成
b 改成 b,然后这是学号、 姓名、
课程还有分数 分数呢是成绩表里头的分数,我们再来执行这一句
没有重复列了,这就是自然连接了
多个表之间的连接呢,除了相等作为条件之外
还可以使用不等作为连接条件,我们称为是不等值连接
比方说我们有一个表叫做成绩表,还有一个表呢叫做
等级表,现在我们的目的呢,是将百分制的这成绩对应成一个
五分制的这样一个成绩。
那我们这个查询语句呢 写成 SELECT
* FROM 表的列表 score 逗号 grade 后面这个连接条件,写
score 点 score,就是分数里头的,就是成绩表里头的 分数
between 在哪一个呢,在等级表里头的
gstart 跟 gend 之间,比方说这个
80 是在 80 到 89 之间的
所以呢,这一行呢就会对应到这一行来,90 呢,是在 90 到 100
之间的,所以这一行呢就会对应到 这个的第一行,这个条件呢,我们还可以写成
WHERE score 点 score 大于等于 grade 点 gstart AND
score 点 score 小于等于 grade
点 gend SELECT 星
FROM score 逗号 grade,这实际上是一个
笛卡尔乘积,后面的筛选条件呢 是成绩表里头的分数在
grade 里头的 gstart 和 gend 之间的时候,我们来建立连接
关系,我们来执行,所以这就是不等值连接,如果我们要想看到 学号、
课程号、 分数和这个级别的话,这个地方
呢,我们就列出所有的字段名
我们再来执行这一句,如果这个字段名呢是
不重复的话,不需要、 或者说不必要加上表名,如果说字段名是重复的话,前头呢就一定加上
表名点
前面的连接,连接条件都写到了 WHERE 子句当中
WHERE 子句呢显得很复杂,一种简化方法就是使用
INNER JOIN 子句,我们称为内连接,那么一般的格式是
SELECT * 或者是字段列表 FROM 表
1 INNER JOIN 表 2 ON 连接规则
1;还可以写 INNER JOIN 表 3 ON
连接规则 2 等等,后面呢,还可以加 WHERE
子句用来对结果呢进行筛选 还可以加 ORDER BY
子句对结果呢进行排序,就是把原来 在 WHERE
当中连接的那些条件,放到了这个 ON 的后面,放到
ON 的后头 这是我们刚才的一个
等值连接,现在呢,我们要把这个等值连接就是用 WHERE
条件 实现的等值连接变成用 INNER JOIN
来实践,我们这个地方写 FROM score
后面呢就写 INNER JOIN,stu
1 ON 后面条件,这个 WHERE
呢就可以不要了,我们来 执行这一句
这就用 INNER JOIN ON 代替了 WHERE
这是呢,我们刚才一个比较复杂的一个连接,我们也可以 呢,把它改成用
INNER JOIN 来实现,这个地方写 FROM score
然后呢是 INNER JOIN
stu1 ON 条件,跟 stu1 之间的条件呢就是
score 的 number 等于 stu 1 的 number,然后
呢,再写 INNER JOIN
下来一个是成绩表,ON 后面条件呢,就是这个条件
成绩表里头的课程号和课程表里头的课程号要是相等的 这样呢我们就可以把后面的这个
WHERE 里头的这个连接条件呢去掉了,后面 呢这个
WHERE 里头呢,就只有筛选条件了
我们再来执行这一句,这个结果呢 也是一样的,就是把
WHERE 里头的连接的条件放到了 INNER JOIN
当中,这样子呢 WHERE
这里头的条件呢就得到了简化。
前面的连接 按照连接条件得到的结果我们称为是内连接
比方说这是我们的
成绩表,这是我们的学生表,使用内连接的时候呢
我们是按照学号相等这样一个规则建立连接的,那么如果
这个学生没有参加考试,那么是查不到的
我们查到的只是那些参加了考试的学生的名字
和分数,如果我们想把没有参加考试的人也列出来,只是呢分数呢
是空白的,那这个时候呢,我们就要使用外连接,外连接
能够查到不匹配项,外连接分为
左外连接和右外连接,左外连接查找左边表的 不匹配项,一般的格式是
SELECT *,或者是 字段列表 FROM 表
1 LEFT OUTER JOIN 表 2 ON
条件,所以这个呢,就相当于是左边这个表,这个呢 就相当于是右边这个表。
如果左边这个表里头跟表 2 里头没有对应项的话
左边这表里头的那条记录会被显示出来,这就是左外连接
那么另外一种外连接呢,叫做右外连接,能够查找到右边那个表里头的不匹配项 使用的格式是
SELECT * 或者是字段列表 FROM
表 1 RIGHT OUTER JOIN 表 2 ON
条件,这种格式呢是说,如果表 2 里头没有跟表 1
对应的项的话,表 2 里头的这些项会被显示出来,这就是右外连接
我们看具体的例子
这是我们刚才的内连接,我们再来看一下这个结果
这里头就记录了是谁哪门课程
分数是多少,就凡是选了课的有成绩的这些
人呢都在这里头,那么我们还记得学生表里头还有一个学生 是
3 号同学,因为他没有选课没有成绩,所以这里头呢
就没有,现在呢,我们把它改成呢外连接,左外连接
LEFT OUTER JOIN score ON stu 1 点 number 等于 score
点 number,我们来看这个结果 看,没有选课的这个学生呢也显示出来了,只不过他的选课的
课程号,学号、 课程号跟分数呢是空的,这就是左外连接
就是左边这个表里头的,也就是 stu 1 这个表里头的不匹配项也显示出来
了,但是反过来呢就不成立,比方说我们要把这个地方改成 score
这个地方呢改成 stu 1 是说
score 里头的不匹配项会显示出来,那么这里头没有不匹配项 自然就不显示出来,所以这就是左外连接
下来我们看右外连接,我们写 SELECT * FROM score
RIGHT OUTER JOIN stu1 ON stu1 点 number
等于 scroe 点 number,那就是说,这是右边这个表 stu
1 里头的不匹配项会被显示出来,所以这个时候呢我们看这边是
成绩表的内容,这边呢是学生表里的内容,学生表里头呢有一个 这个
03 号同学有不匹配项,但是呢,由于是右外连接,所以呢这个
03 号同学信息 呢会被显示出来,这就是右外连接
今天我们学习了
多表连接查询,其中包括笛卡尔乘积、 等值连接
不等值连接,内连接和外连接 一般的格式是这样子的,除了连接之外
后面可以加 WHERE 条件,用来对连接的结果 进行筛选,可以加
GROUP BY 子句 对查询的结果呢进行分组,可以加
HAVING 条件 对分组以后的结果呢进行筛选,可以加
ORDER BY 子句 对结果呢进行排序
[空白音频]