【MySQL数据库】 五

本文主要介绍了如果根据表之间的关系设计表,以及mysql的聚合/分组/联合查询. 

一.表的设计

实体和关系的四种关系

1.一对一

一个账号只能对应一个学生;

一个学生只能有一个账号;

比如:账号表和学生是一对一的关系

* 可以在账号表中引入学生id

* 也可以在学生表中引入账号id

【MySQL数据库】 五_第1张图片

2.一对多

一个学生只能在一个班级;

一个班级可以包含多个学生;

【MySQL数据库】 五_第2张图片

3.多对多

一个同学可以选择多门课程来学习;

一个课程可以被多个同学来选择;

往往表示多对关系,需要引入一个关联表

【MySQL数据库】 五_第3张图片

4.没关系

如果两个实体没有关系,那么两张表就完全独立,互不影响


上述这几种数据库表的设计方式都是最常见的.

二.查询高阶

1.insert+select

将select查询结果插入到另一个表中

要求查询的列的个数/类型和被插入的表一致

【MySQL数据库】 五_第4张图片

2.聚合查询

行和行之间的运算

>聚合函数

count( distinct 表达式 )

返回查询到的数据的数量

sum()

返回查询到的数据的总和,非数字无意义

avg()

返回平均值,非数字无意义

max()

返回最大值,非数字无意义

min()

返回最小值,非数字无意义

  • count

【MySQL数据库】 五_第5张图片

count(*) 如果是一行全空记录,仍然会被算在被

count(某列) 空值不会算在内

注意:count和( )必须要仅仅黏在一起,否在报错

  • sum

求和,把这一列的若干行,进行累加

只能针对数字进行相加

【MySQL数据库】 五_第6张图片

对字符串进行求和 , 没有效果,并且会产生警告

3.分组查询

上述的聚合函数是把表中的所有行都放在一起

有的时候,希望把数据进行分成多组来进行计算

Group by子句

指定一个列,按照这一列进行分组 ; 这一类中,数值相同的行,会被分到一组

每个分组都都可以使用上述的聚合函数进行计算

计算1班和2班的语文/数学平均分(以班级分组)

【MySQL数据库】 五_第7张图片

select中指定的列必须是必须是group by 指定的列 ,

如果select中想用其他的列,其他列必须放到聚合函数中, 否则此时查询的结果无意义.

比如 name只是分组的第一个代表,它实际上并没有什么意义

【MySQL数据库】 五_第8张图片

分组查询,也可以搭配条件来使用

1.分组之前的条件

where

2.分组之后的条件

having

1.分组之前的条件

比如,在分组之前有一个排除张三的条件

【MySQL数据库】 五_第9张图片

2.分组之后的条件

分组之后的条件也要搭配聚合函数来使用 !!

比如求每个班级的语文平均分>70的

【MySQL数据库】 五_第10张图片

3.同时包含分组前的条件和分组后的条件

求每个班级除去张三之后的平均分>70的班级

在实际开发中,可能会涉及到一些比较复杂的sql, 但是sql写复杂了其实是不好的

可读性不好和执行效率都可能比较差 , 不建议写太复杂的sql  ! 

4.联合查询

也叫多表查询 , 最复杂的写法

3.1 内连接

select  字段 from 1 , 2 where 连接条件 and 其他条件

或者

select  列名 from 1  inner join  2 on 连接条件 and 其他条件

(用inner join/join来连接表 , 用on来表示连接条件 )

eg.

【MySQL数据库】 五_第11张图片

笛卡尔积(数学上的运算)

就是把两个表的记录,按照排列组合的方式,构造成一个更大的表

笛卡尔积的列数: 两个表的列数之和

笛卡尔积的行数: 两个表的行数之积

针对任意两张表都可以计算笛卡尔积

笛卡尔积是一个非常低效的操作,尤其是表的本身的记录比较多的情况

笛卡尔积中有些数据是符合实际情况的,有些事不符合实际情况的

所以需要用连接条件来筛选符合实际情况的数据


示例:

a.两个表进行笛卡尔积

将学生表和班级表进行笛卡尔积

【MySQL数据库】 五_第12张图片

b.指定连接条件

增加连接条件

如果是多表查询,条件中最好写作  表名.列名   的形式

【MySQL数据库】 五_第13张图片

笛卡尔积+必要的条件= >多表联合查询


  • 查询lisi同学的所有成绩

【MySQL数据库】 五_第14张图片

  • 求每个学生的总成绩

【MySQL数据库】 五_第15张图片

  • 求每个学生选了几门课

【MySQL数据库】 五_第16张图片

  • 查询所有同学的成绩,课程名字和分数(三张表进行笛卡尔积)

【MySQL数据库】 五_第17张图片

注意此处能够写出连接条件是因为这几个实体之间存在关联关系

3.2外连接

join on 还可以表示外连接

外连接 VS 内连接

1.

左侧表的每一条记录,都能在右侧找到对应;

右侧表的每一条记录,也能在左侧找到对应;

【MySQL数据库】 五_第18张图片

此时,这两个表,进行内连接和外连接的结果完全相同 ;

2.

此时这张表并不是相互一一对应的

【MySQL数据库】 五_第19张图片

内连接产生的结果,一定是两个表中都存在的数据 (公共的部分)

外连接在mysql里有两种情况 ,左外连接 / 右外连接 left join / right join

1.左外连接 . 就是以左侧的表为主.

左侧表的每个记录都会在最终结果里 ;

如果某条记录左侧有,而右侧没有,就把对应的列设为空值

【MySQL数据库】 五_第20张图片

2.右外连接,以右侧的表为主

【MySQL数据库】 五_第21张图片

还有一种outer join 全外连接,就是左外连接和右外连接求并集 (mysql不支持)


注意:

多表联合查询的使用,一定要克制 , 既会影响到运行效率,又会影响到开发效率 (可读性差)  , 所以千万不要以写复杂sql为荣!

 3.3 自连接

本质上是自己和自己做笛卡尔积,本质是把行之间的关系转换为 列之间的关系

SQL中编写条件,条件都是列和列之间进行比较 , 但是SQL无法进行行和行之间的比较, 但是 把行转换成列 就好办了

 *  计算1号课程成绩小于2号课程成绩的同学

2.4子查询

日常开发中,使用子查询,更要克制!

*   查询和张三同学同班的同学

【MySQL数据库】 五_第22张图片

就相当于套娃 ,把两个sql 套在一起

不建议这么写 ,开发效率和可读效率都不高.

注意: in / exsits 也是可以使用的

2.5合并查询

union/union all 合并查询,把多个select查询到的结果集合合并成一个集合

合并的前提是两个查询的结果集,列是对应的

or也是把一些结果合并出来,只能局限在一个表里,

union可以针对任意连个表;

总结:

【MySQL数据库】 五_第23张图片

红框重点掌握,面试考察!

你可能感兴趣的:(MySQL数据库,数据库,mysql,oracle)