MySQL(5)

MySQL(5)

前言:

本文 将学习 表的 设计 和 聚合查询 ,联合 查询。

在进入 文章前我们 来 复习 一下 上文内容

  1. 修改 : update 表名 set 列名 = 值, 列名 = 值 .... where 条件

    注意 : 此处的修改是 是针对"满足条件"的记录修改

  2. 删除 : delete from 表名 where 条件

    注意 :通过 where 指定 删除的 具体记录,这里就需要保证where 的条件是正确的,如果这里没有where,这就会删除整个表的数据。 



3. 约束 操作

约束类型说明
not null如果尝试 插入 空值(null) 就会直接报错。
unique表示 数据 唯一 (如果尝试 插入 重复 的 值 也会 报错)。
default约定 一个 默认值。
primary key主键 约束 相当于 数据 的唯一 身份标识(类似 身份证 号码/ 手机号)
foreign key外键 描述两个表之间的关联关系,表1 里的 数据 必须在 表2 中 存在。


注意 : foreign key :只要 子表 依赖 了 父表那么 子表 和 父表对应 的记录 是 不能删除,直接删除表 同样也是不行的。

另外 : 这里 子表想要修改 依赖父表的那一列,如果 修改的值 相对于 父表 的那一列 不存在 那么 同样是不能 修改的。

更多细节 可以 回顾 一文,下面我们就来学习一下我们的 表设计。

表的 设计

解释: 这里 表的设计数据库的设计 其实 就算根据实际问题场景,把表给设计出来。

这里我们 表的 设计 会 比较抽象,(关于设计相关的话题,都会比较抽象,这里一般需要大家有 一定经验)。

那么这里 就只会 浅浅的讨论 一下。

下面我们 来 看一个问题场景。

问题场景: 如何设计 数据库,如何设计表? (可能 有人 说所 我要会还来看博客?)

这里我们就 直接 给出一个 典型 的通用 办法 : 先找出这个场景中涉及的 “实体” , 然后 在分析"实体之间的关系".

实体: 这里 实体 类似 于 对象(javaSE中的面向对象中的对象 ,这里 的 类和对象 从 需求中 提炼 出来。)这里 实体 也 类似,那么这里

实体 就可以视为

是需求中的 一些 关键性 的 名词 。

这里就来 一个典型的场景:

学生 管理系统

  1. 表示学生的 基本信息.

  2. 表示班级的基本信息.

  3. 表示学生学习的课程的基本信息.

这里的 关键 名称 就为 学生, 课程, 班级,这里就是 我们所谓的实体,对于实体来言,我们就需要创建对应 的表来表示相关的信息。

注意: 很多时候 实体 与 实体 之间并不是孤立的,而是 存在 对应关系, 这样的 对应关系,也需要 体现 在表中。

(实体之间的关系,这个是 隐含的,是需要进一步分析才能想清楚的,这里实体之间的不同关系,会对表的设计产生直接的影响)。


下面我们来看一下 实体之间 的关系。

这里 我们 分析 实体 之间的 关系 好比 小学生造句 ,所以 不要 怕。

1. 一对一的关系

例子:每个中国本土居民和他们唯一的身份证编号。

在这里插入图片描述

这里我们 在 来 以 学习通 来举例子


学生表: student 表 (学生 id , 学生 姓名 ,学生班级…)

用户表 : user表(用户 密码, 密码…)

这里 : 学生 是 一个 实体 , 用户 是 一个 实体, 那么我们 来 造句 。

一个 账户 对应 一个学生 , 一个 学生也只有 一个 账户。

这里 就为 一一对应 的 。 下面我们来 在数据库 中 表示 一对一的关系 。

方法 一 : 可以 把这两个实体用 一张表来表示

方法二 : 可以 用 两张表表示 ,其中 一张 表 就包含了 另外 一张表的 id

如 : student 表 (学生 id , 学生 姓名 ,学生班级… user_id)

​ user表(用户 密码, 密码… student_id)

这里我们就可以 根据这个对应 关系 (user_id, student_id),随时 找到某个账户对应的学生是谁,也能找到某个学生对应的账户是啥。

2. 一对多的关系


例子:一个年级段有多个平行班级,多个平行班都隶属于一个年级段。

在这里插入图片描述

这里 在 以 学生和 班级 举例子:

学生表 : student 表 (学号, 姓名 …)

班级表 :class 表 (班级编号, 班级名称…)

这里 实体 为 学生 和 班级 , 下面 我们 来 造句 。

一个学生 应该 处于 一个班级当中, 一个班级可以包含多个 学生。 (学生 对一 一个 班级, 班级 可以 对应多个学生,所以这里 就为 一对多的关系)。

这里 在数据库 中 表示 一对 多 的关系,也有两种典型的方案:

方法一 : 在班级 表中 ,新增 一列,表示这个班级里的 学生id 都有啥。

student 表 (学号, 姓名…)

class 表 (班级编号, 班级 姓名, 学生列表)


如:

class 表

班级编号班级名称学生列表
1高一 一班1 , 2 , 3 , 4, 5
2高一 二班6, 7,8,9,10

这里 通过 这种方式(学生列表),就可以表示 一个班级都 对应 到那些同学,


方法二 : 班级表 不变, 在学生表中,新增一列classId (与外键 哪里 差不多)

class 表 (班级编号, 班级名称)

班级编号班级名称
1高一一班
2高一二班


student 表 ( 学号, 学生 姓名,所在班级 )

学号学生姓名所在班级
1张三1
2李四1

这里就可以 根据 所在班级的 编号 也同样 也能知道 一个 班级对应到那些同学 。

注意: 对应 MySQL 来说 , 表示 一对多 的时候 只能采用方案二 不能 采用 方案一,因为 MySQL 没有 提供 数组 这样的 类型。

方案 一 学生列表 那 一些 是 一组 数组 ,需要 通过数组来保存。 MySQL 中没有 数组类型,所以 不能 采用 该方案。

但 MySQL 中 没有数组 ,不能使用 方案 一 ,但 有些 数据库 是 可以的 如 Redis 这样的 数据库就有数组,就可以 考虑使用方案一的方式来表示。

3. 多对多的关系

举例: 一个班级有若干个老师,一个老师也可以带若干个班级。

在来一个 例子 : 学生 与 课程 。

学生表 (学号 , 姓名)

课程 表 (课程编号,课程名字)

实体 学生 , 课程

造句 : 一个 学生可以 选 多门 课程, 一门课程 可以 包含 多个 学生 (M 和 学生 可以选 N 们 课 )

这里 多对 多 关系 在 数据库设计中 ,就 可以 使用 一张 关联表 来表示 两个 实体之间的 关系 。

学生 表 (学号, 姓名 )

学号姓名
1张三
2李四
3王五

课程 表 (编号, 名称 )

编号名称
1语文
2数学
3英语


学生 - 课程 表(学号, 课程编号)

学号课程编号
11
12
31

在这里插入图片描述

上面 就为 我们 表 或 数据库 的 基本设计思路, 这里 可以 总结 成 一句话, 先找 实体,再找关系,实体就算 关键性的 名词,每个实体都需要分配成 一张表,然后我们还需要考虑 实体与 实体之间的 关系 不同的关系 在设计表 又会 有 不同 的设计 方式 ,如 一对一 ,一 对 多, 多对多。

补充: 有的时候,为了 更方便的表示 / 找到,实体之间的关系(求其是针对比较复杂的场景)还可以通过画 ER 图的方式来表示。

上面这些内容 比较抽象,下面我们来 看 一些比较具体的 操作,如:对查询进一步的扩充。

查询操作的 扩充

1.新增


和查询 操作 结合 在一起 的 新增 操作。

把 从 上一个表重点查询 结果作为 下一个表要插入的数据。

演示:

1.我们 先来创建 一张表 A 并 插入 3 条 记录

在这里插入图片描述


2.再创建 一张 表 B

在这里插入图片描述

3.将A的 记录 插入 B 中, 使用 我们 这里 的 新增 操作。

在这里插入图片描述

可以看到我们 成功 的 将 A 的 记录插入 到 B中 (再 这个 语句中会 执行 查找,针对查找的每个结果,都会执行 插入操作,插入 B中)

注意: 这里我们 需要保证查询出来的结果的列数 和类型和B 表匹配。

补充 : 如果 我们 这样创建 B (name varchar(20), id int); 那么 还能 将 A 插入 到 B 中 吗?

在这里插入图片描述

​ 这里 我们 就 不用 统配符 * 而 使用 指定列 来查询 主动 调换 结果 顺序

(本来 id 在 前, name 在后 ,和B 不匹配,但是可以通过针对A 进行指定列查询,从而可以保证插叙的结果顺序能和B对上 )

在这里插入图片描述

所以 这样 也是 可以 顺利 插入的 。。

另外: 还可给 select 指定 一些 其他的条件/ 排序/limit /去重 …

注意 这里 插入的 实际就是 select 执行结果 的 临时表。 (查询的结果是在临时表中,插入查询的结果 ,是 放入到数据库的 硬盘当中 insert 改的 是 硬盘中的数据)。

2.聚合查询


聚合查询: 将多行 之间的 数据 ,给 进行 聚合了(把多个行的数据进行了 关联的操作)。

在 具体 了解 聚合查询 之间我们 先来 了解 一下MySQL中内置的 一些聚合函数。

函数说明
count( 列名 / 表达式 )返回查询到的数据的 数量(查询结果有多少行)
sum (列名 / 表达式)返回查询到的数据的 总和,不是数字没有意义
avg (列名 / 表达式)返回查询到的数据的 平均值,不是数字没有意义
max (列名 / 表达式)返回查询到的数据的 最大值,不是数字没有意义
min (列名 / 表达式)返回查询到的数据的 最小值,不是数字没有意义


注意: 这里 参数都可以 加上 一个 distinct 去重操作。

下面我们 来 具体 演示 一下 :

1.创建 一张 表

在这里插入图片描述

2.这里我们 给 他 插入 一个 空的 数据 ,方便后面 特殊例子举例

在这里插入图片描述

准备 工作完成 我们 来使用我们的 聚合 函数 。

count 返回查询到的数据的 数量

演示:

在这里插入图片描述


针对 select * from exam_result 的 结果集合进行计算行数。

另外 : 这里我们 还可以指定某个 列 来进行查询 (这里 count 的参数 不一定非要写成 *).

在这里插入图片描述

但是 这里 只有 7 ,与上面 的 8 不吻合, 这了 就是 相差到 NULL 这个 数据上,这了我们来 直接 查询 看一下 结果

在这里插入图片描述

这里 就会 直接忽略 NULL 并不会 计入 到我们的count 中。

sum 进行求和(excel 里面的求和)

解释: 把 这一列 的 若干行 ,进行 相加。

演示 : 将 语文 成绩 进行 求和
在这里插入图片描述


这里 的NULL 不 会 算进去。

在这里插入图片描述

可以看到这里 就 成功 将 语文 成绩 进行求和。

这里 还可以 使用 多个 sum 来 操作

演示 : 将 语文 成绩(总成绩) 和 英语 成绩 (总成绩)相加。

在这里插入图片描述

这里 就 相当于 表达式 查询。

这里 聚合函数 里面的 参数 也可以 通过表达式的方式进行 运算。

在这里插入图片描述

这里 聚合 函数 也相当于 表达式的 一部分。

注意: sum 这个操作 只能针对数字进行运算,不能针对字符串来进行。

这里我们 就来 演示 一下 通过 字符串 来 进行 sum 操作

在这里插入图片描述

这里 我们 就 出现了 8 个 异常 (warnings) , 那么我们使用 show warnings来查看 一下 这些 异常

在这里插入图片描述

这里我们 尝试针对 字符串使用 sum 就会出现 上面的这些问题 (不正确的 截断 字符串 无法 转化 为 double)。

另外 这里 我们 的 聚合 函数 还可 以搭配 where 字句 来使用。

可以基于 条件进行筛选,把筛选结果,再进行聚合。

演示: 英语成绩 大于 70分 的 总和

1.先打印出 全部成绩(方便下面 对比)

在这里插入图片描述

2.使用 sum 函数,先将 英语成绩 求和 (方便下面对比)

在这里插入图片描述

3.使用 where 字句, 控制 只计算 大于 70的 英语成绩。

在这里插入图片描述

这里就可 得出 结论 : 形如 以上操作,就会先执行条件筛选 然后再执行聚合。

下面我们 再来 演示 一下 avgmaxmin 因为 与sum操作类似 ,下面 就 只会 简单的 演示一下

avg 返回查询到的数据的 平均值

演示: 求 数学 成绩的 平均值

1.先查看整张表 (方便对比)

在这里插入图片描述

2.使用 avg 求 数学成绩的平均值。

在这里插入图片描述

可以看到我们 就 通过 avg 求出了 数学的 平均成绩

注意: 计算avg 的时候 ,NULL 这样的记录是不记录其中的,不会影响平均值的结果。

演示: 语文成绩的平均值。

1.查询 所有 记录(方便对比)

在这里插入图片描述

2.查询 语文成绩的平均值(注意: 此时没有删除 空值 NULL)

在这里插入图片描述

3.删除 张三

在这里插入图片描述

4.求 语文成绩的平均值

在这里插入图片描述

这里 也就 证明了 计算avg 的时候 ,NULL 这样的记录是不记录其中的,不会影响平均值的结果。

max 返回查询到的数据的 最大值

演示: 求 数学成绩中的 最大值

1.先查看整张表 (方便对比)

在这里插入图片描述

2.使用max 求数学 成绩的 最大值

在这里插入图片描述

min 返回查询到的数据的 最小值

演示: 求数学成绩中的最小值

1.先查看整张表 (方便对比)

在这里插入图片描述

2.使用 min 求 数学成绩中的 最小值

在这里插入图片描述

分组操作


分组操作: group by

根据行的值,对数据进行分组,把值相同的行都归为一组。

演示: 查询每个 角色的最高工资,最低工资和平均工资 (这种操作就需要按照 岗位 进行 分组)

1.这里我们先来构建一张员工表

在这里插入图片描述

2.查看记录 (方便 下面对比)

在这里插入图片描述

3.使用 grop by 进行 分组操作

这里 使用 group by role 就算 根据 role 这 一列 进行 分组

在这里插入图片描述

在这里插入图片描述

先 执行 分组操作(group by)再 根据 分组分别执行 每个 组的聚合函数 (根据每个 组 求 最大 最小 和 平均 值)。

这里 我们 同样可以使用别名

演示:

在这里插入图片描述

针对 分组 之后 ,得到 的 结果 ,可以 通过 having 来进行 指定 条件。

(group by 是 可以 使用 where ,只不过where 是再分组 之前执行,如果要对分组之后的结果进行条件筛选,就需要使用having)

这里 来 举例 :

分组 之前指定 条件: 求 角色 平均薪资。去掉马云的平均薪资。

这里就是 先去掉马云 ,然后 再分组 (分组之前指定条件,就要使用 where)

1.查询分组后的数据

在这里插入图片描述

2.加上条件 观察 区别

在这里插入图片描述

分组之后 指定 条件筛选

演示 : 求 每种角色 , 平均 薪资,只保留平均薪资1w 一下。

这里就是 得 先分组计算,知道了平均工资,才能进一步的筛选。 (分组 之后 指定的 条件, 就需要使用 having).

1.查询分组后的数据 (方便下面 进行 对比)

在这里插入图片描述

2.使用 having 观察 区别。

在这里插入图片描述

补充: 这里 我们 可以 同时 有 where 和 having

这里就来演示 一下:

在这里插入图片描述

这里 就 通过 where 再 分组 前 将 马云去掉 , 通过 having 将 分组 后 平均 薪资 高于 1 w 的董事长 去掉了。

3.联合查询(多表查询)


联合查询: 把多个表的记录 往 一起 合并,一起进行查询。

注意: 多表查询 是 SQL中 最复杂的部分,也是 笔试中爱考的部分,但是实际开发中一般禁止 使用多表查询。

在学习 多表查询 之前我们 要先 学习 一下 笛卡尔积 (多表查询的核心操作)

笛卡尔积


这里 可以 自行 百度搜一下 笛卡尔积 看看人家 的故事, 这里我们 就直接来 了解 笛卡尔积干了啥。

笛卡尔积 : 是 针对 任意两张表之间进行运算。

这里我们 来 创建 两张表 来 理解一下 笛卡尔积 操作。

学生表 (studentId, name ,class)

studentIdnameclass
1张三1
2李四1
3王五2
4赵六2

班级表 ( classId, name)

classIdname
1高一一班
2高一二班
3高一三班

笛卡尔积的运算 过程:

先拿 第一张表 的 第一条 记录 和 第二张 表的每个记录,分别 组合得到了 一组新的记录。

这里 先拿 第一张表的 第一条记录 与 班级 表组合。

studentIdnameclassclassIdname
1张三11高一一班
1张三12高一二班
1张三13高一三班

这里就完成 了 学生 表 第一条 记录 与 班级表 的 组合。

这里 继续:

studentIdnameclassclassIdnaem
2李四11高一一班
2李四12高一二班
2李四13高一三班


最后 表 一 的 每一条记录 都会 与 表二 的每条记录 组合 , 最后 像上面 得到的 记录 就会 有 4 * 3 = 12 条 记录 (这就是 笛卡尔积 最总的 效果)。。

注意: 针对 A B 两张表 计算 笛卡尔积 此时 笛卡尔积的列数 就算 A 的列数 + B的列数,笛卡尔积的行数 就算 A 的 行数 * B 的行数。

另外 : 这里 如果 A B 两张表都非常大 贸然 执行 笛卡尔积 很可能 就会 将数据 搞挂。

这里 在 SQL 中 使用 笛卡尔积 的 最简单做法,就是直接 select, from 后面跟上 多个表名( 表名之间使用逗号分割);

演示:

1.创建 学生表 和 班级表

学生表:

在这里插入图片描述

班级表:

在这里插入图片描述

2.进行笛卡尔积操作 select, from 后面跟上 多个表名( 表名之间使用逗号分割);

在这里插入图片描述

这里我们 就完成了 笛卡尔积操作。

笛卡尔积这个操作,虽然执行效率不高(笛卡尔积 是一个 单纯 无脑的排序组合,这里的组合结果不一定都是 有意义的数据),但本身确实 是一个功能挺好的操作,可以 借助笛卡尔积,来完成一些复杂操作。

这里我们 就通过 笛卡尔积 来 查询 一下同学的 姓名和 对应 的班级名字。

刚刚 创建两张 表是 我们 创建了 class 和 classId这两列 ,让 学生表 和 班级表 产生 相连 的 关系 ,这里我们 就可以 通过 这 里的关系 ,将笛卡尔积 中无意义的数据 ,给 剔除掉 (class 和 classId 相等 就 保留 )。

在这里插入图片描述

这 还可以 使用 表名 . 列名 来表示 这里就可以 防止 重 命名的 情况 如 : classId = classId

这里 就需要 改成 student.classId = class.classId即可

在这里插入图片描述

如果这里我们 指向要 同学 名字 和 班级 姓名 同样 是可以 指定列的 。

如:

在这里插入图片描述

这里 就 将通配符* 换成了 我们的 student.nameclass.name 将我们 需要 的 同学 姓名 和 班级姓名 打印出来了。

知道了 笛卡尔积 操作 ,那么解析来我们 来学习 一下 多表 查询 操作。

多表查询

准备工作 : 创建 4 张 表 来 演示 我们 的 多表查询 操作。

--准备工作
--  if not exists即如果不存在,if exists即如果存在

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

-- 删除 之前数据库 肯能 存在 的表


-- 创建班级表
create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

-- 学生表
create table student (id int primary key auto_increment, sn varchar(20), name varchar(20), qq_mail varchar(20), classes_id int);


--  课程表
create table course (id int primary key auto_increment, name varchar(20));

-- 成绩表
create table score (score decimal(3,1), student_id int, course_id int);

-- 插入 数据
insert into classes(name, `desc`) values

('计算机系20191', '学习了计算机原理、CJava语言、数据结构和算法'),

('中文系20193','学习了中国传统文学'),

('自动化20195','学习了机械自动化');

insert into student(sn, name, qq_mail, classes_id) values

('09982','黑旋风李逵','xuanfeng@qq.com',1),

('00835','菩提老祖',null,1),

('00391','白素贞',null,1),

('00031','许仙','xuxian@qq.com',1),

('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),

('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

insert into score(score, student_id, course_id) values

-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),

-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),

-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),

-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),

-- 不想毕业
(81, 5, 1),(37, 5, 5),

-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),

-- tellme
(80, 7, 2),(92, 7, 6);

在这里插入图片描述

准备工作完成 ,接下来 来 完成我们 的 问题 、

1.查询 许仙 同学的成绩。

演示:

这里我们 先来 分析 一下 : 这里 我们 需要 查询许仙同学 的成绩,那么 我们 需要 先 知道 他 选了 那些门课(没选 咋来的成绩 是不是),这就可以 通过 学生表,获取学生信息(如 : 学生 姓名等 ), 然后 通过 分数表 获取 学生成绩 。

这里我们 就可以 通过 笛卡尔积 结合 学生 表 和 分数表 进行 查询。

1.对 学生 表 和 成绩 表 进行 笛卡尔积 操作。

在这里插入图片描述

中间的 信息 省略 (太多了)。

在这里插入图片描述

左后 可以看到 有 160 条 信息 (学生 8 个 , 成绩 20 相乘 等于 160 )。

2.通过 关系 筛选 出我们 需要的 数据。

仔细 观察 就能 发现 ,在当前 的这 两张 表里,都存在 学生 id 这一列, 按照 前面 总结的规律,应该指定 这 两个 id 匹配,才能 保留 记录, 不匹配的就属于是排列组合直接生成的无效数据。

在这里插入图片描述

这里我们 加上连接 条件,就 将我们 想要的数据 筛选出来了。

在这里插入图片描述

这里我们 想要 许仙 同学的 成绩 ,那么我们 在加上 一些 条件 即可。

在这里插入图片描述

这里我们 就 拿到 了 许仙 同学的 成绩。

这里 同样可以 指定 列 来 查询

在这里插入图片描述

补充: 这里我们 刚刚学习 多表查询到时候,千万不要试图 一步到位(一步就将SQL 写出来) ,所谓心急吃不了热豆腐吗。

这里我们 刚开始的 时候 ,一定是 一点一点的写,先分析数据来自那些表,然后笛卡尔积,观察笛卡尔积的结果,筛选出合法的数据,再逐步的根据需求,添加新的条件,让结果数量一点一点的接近预期。

基于关键字 join完成 多表查询。

格式:from 表名 jion 表二 on 条件 ,

上面 一种的 格式 from 表一 ,表二 where 条件

这里 实现 多表查询 除了 直接 from 多张 表,这一种写法,还有 另 一种 写法 基于join这样的关键字也能实现 多表查询。

在这里插入图片描述


下面我们 继续

2.查询所有同学的总成绩 ,及 同学的个人信息 :

这个 例子 需要 再 多表查询 的基础 上再加上 一个 聚合查询。

1.显示每个 同学 每个 科目 的 分数

在这里插入图片描述

这里 可以 看到,同学的分数 是按照行 的方式 来排列的

如 :

在这里插入图片描述

这里 就需要 正对 我们 的行与 行 之间的 计算 就需要我们的 聚合 查询 。

2.分组操作 group by

在这里插入图片描述

分组 之后 ,可以看到,当前这里的score 列并不是总成绩而是每个分组中 的 第一条记录。

这里我们要 求 总成绩 只需要 再 此基础上 加上 一个 sum 操作。

在这里插入图片描述

这里我们 就 得出 了每位同学的 总成绩。

最后我们 再来 看一个 例子

3.查询 所有同学 的成绩, 及同学的 个人信息

这里 不光 要查询 出 同学的名字 ,还有 课程的名字,以及分数。

这个时候 就涉及到 三张 表的 联合查询了。

同学 名字 --》 学生表

课程名字 --》 课程 表

分数 – 》 分数表

这里 三 张 表 算 笛卡尔积 与 两张表 规则是 一样的(前两张 笛卡尔积 合成 一张 大表,再与最后一张表,笛卡尔积)。

1.对三张表笛卡尔积

在这里插入图片描述

中间记录 省略


这了 960条记录( 学生表 8 个 记录 , 分数表 20 个记录 , 课程表 6 个记录)。

注意: 这了 中间 步骤我们 先使用 * ,方便查看结果,最后一步 再换成 具体的 列。

2.加上连接条件

仔细 观察 我们 可以 看到 这里的 连接条件。

在这里插入图片描述

这里我们 分数表 中 既有 学生 id 又有 课程 id 那么我们就可 通过 的 学生id 和 课程 id 进行 筛选。

在这里插入图片描述

使用下面 SQL 中 完成 查询。

select * from student, score, course
where student.id = score.student_id
and course.id = score.course_id;

在这里插入图片描述

最后 去掉 不必要的列 保存 我们 需要的 (学生姓名 ,课程 名字 , 学生 分数)

这里 就 只需要将 * 换为 student.name, course.name, score.score 即可。

在这里插入图片描述

补充:这里 同样 是 可以 使用 关键字 join表名 on 条件 来 完成

多张表 使用 join 格式 from 表1 jion 表2 on 条件 jion 表3 on 条件

在这里插入图片描述

select student.name, course.name, score.score from student
join score on student.id = score.student_id
join course on course.id = score.course_id;      
-- join后面 跟 表名  
-- on 后面 跟 条件

补充:

这里 from 多个表 where 写法 叫做 “内连接”

使用 join on 的 写法 既可以表示 内连接,还可以表示外连接。

这里 select 列 from 表1 inner join 表 2 on 条件; inner join 表示 “内连接” 其中 inner 可以省略。

select 列 from 表1 left jion 表 2 on 条件 ; 左外连接

select 列 from 表1 right jion 表 2 on 条件 ; 右外连接

左右 连接 表示 查询 结果 有 不同的 效果。

这里 举 个 实际 的 例子 来理解 。

这里我们 先来创建 两张 表 学生表 和 班级 表

create table student (id int, name varchar(20), classId int);

create table class (id int, name varchar(20));

insert into student values(1, '张三', 1);

insert into student values(2, '李四', 1);

insert into student values(3, '王五', 2);

insert into student values(4, '赵六', 3);

insert into class values (1, '高一 一班');

insert into class values (2, '高一 二班');

在这里插入图片描述

这里我们 再 举 一个例子 ,将 左右 连接 都 使用 上

这里同样 创建 两张表

--学生表
create table student (id int ,name varchar(20));

-- 分数表
create table score (student_id int, score int);


-- 插入 数据

insert into student values (1, '张三'), (2, '李四'), (3, '王五');

insert into score values (1,90), (2,80), (4,70);

在这里插入图片描述

补充: 全外连接

在这里插入图片描述

这里 就先 讲到这里 ,下面 还有 几种 连接方式 下文 在 继续 补充。

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值