【MySQL】增删改查-进阶(二)

目录

🌴新增

🎄查询

🚩聚合查询

🏀聚合函数

[🏀group by子句](#🏀group by子句)

🏀HAVING

🚩联合查询

🏀内连接

🏀外连接

🏀自连接

🏀子查询

🏀合并查询

🌲MySQL增删改查总结


🌴新增

插入和查询结果:把一个表的查询结果插入到另一个表中

将表名2的查询结果插入表名1中

insert into 表名1 select * from 表名2

需要查询到的结果集合的类型和列数,要和带插入的表的列数和类型匹配以及顺序也要匹配,列名无所谓。

🎄查询

🚩聚合查询

前面谈到表达式查询,主要运算列和列之间,还有情况需要行和行之间的运算,就需要聚合查询

如创建一个考试成绩表:算某个学科的平均成绩,总成绩

🏀聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有:

注意:在sql语句中,聚合运算遇到NULL会直接跳过!函数中的distinct(去重)可写可不写

案例举例:

  • COUNT

全列查询:

查询指定列:

  • SUM
  • AVG
  • MAX
  • MIN

🏀group by子句

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是"分组依据字段",其他字段若想出现在SELECT 中则必须包含在聚合函数中。

创建一个员工表:

我们就可以按照岗位这一列进行分组

查询每个岗位下分别有多少人:

按照每个岗位,计算同一岗位的工资均值:

🏀HAVING

GROUP BY 子句进行分组之前,需要对表中结果去除时,使用where,放在group by之前

出去张三之外,查询每个岗位的平均工资:

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用 HAVING,放在group by后面

查询每个岗位的平均工资,除去平均工资超过两万的:

上述两种条件同时存在:计算每个岗位的平均工资,但是除去张三和平均工资超过两万的

🚩联合查询

上述介绍的都是单表查询,实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。

那什么是笛卡尔积呢?看下图:由第一张表中的第一条数据与第二张表中的第一条数据拼接放到一个大表当中,再由第一张表中的第一条数据与第二张表中第二条数据拼接,依次进行排列组合。通过这样的排列组合得到一张更大的表,这就是笛卡尔积,它的列数由原来两张表的列数之和,行数为原来两张表行数之积。

在SQL中,可以通过select很方便的完成笛卡尔积

select * from 表1, 表2;

创建两个表:

笛卡尔积:

上述结果中,存在一部分无效数据,也就是不符合客观情况,例如第二条数据。这是由于笛卡尔积是全排列的过程,会枚举出所有可能的情况,自然会产生一些不符合实际情况的数据。

去掉无效数据:只需要两列的classId相等即可,注意条件不能写classId = classId,它是分不清哪个是哪个的classId,只需显示加上表名即可。这种专门来筛选出有效数据的条件也称为"连接条件"

联合查询具体使用:

首先我们先初始化一些数据,方便后续查询

所创建表结构如下:

接下来我们插入一些数据:

插入数据后表结构如下:

上述4张表,有3个实体:学生,班级,课程,score为学生和课程的关联表,顺带上分数。

接下来进行我们的查询操作

🏀内连接

内连接也称为等同连接,返回的结果集是两个表中所有相匹配的数据,而舍弃不匹配的数据。也就是说,在这种查询中,DBMS只返回来自源表中的相关的行,即查询的结果表包含的两源表行,必须满足ON子句中的搜索条件。作为对照,如果在源表中的行在另一表中没有对应(相关)的行,则该行就被过滤掉,不会包括在结果表中。内连接使用比较运算符来完成。

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;

select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

案例:

  • 查询'许仙"同学的成绩

写法一:

确定信息来自哪张表,在进行笛卡尔积

指定连接条件(由某个列在两个表中同时存在),去掉无效数据

只显示"许仙"同学的成绩

写法二:join on

  • 查询所有同学的总成绩,及同学的个人信息(学生名字)

求总成绩是行和行之间的运算,需要使用聚合函数,且要针对学号/名字进行分组,再求和。

针对学生表和分数表进行笛卡尔积

指定连接条件

按照学生/姓名进行分组,求和

  • 查询所有同学的名字,课程的名字,以及课程的成绩

此时就涉及到三张表的联合查询。

方法一:

对学生表,课程表,分数表进行笛卡尔积

指定连接条件,三个表需要两个连接条件

不需要补充其他条件,只需显示出所需要的

方法二:使用join on

🏀外连接

外连接和内连接一样,都是基于笛卡尔积的方式来计算的,但是对于空值/不存在的值处理的方式有区别!

创建一个数据库:

上述这两个表是"一对一"的关系,学生名字和分数都是通过id关联起来的,任何一个学生数据,都是能够在分数表中找到分数结果,任何一个分数结果,都是能够在学生表中找到名字信息。

在数据"一一对应"的情况下,进行内连接和外连接结果都是一样的。

内连接:

外连接只能使用join on的方式来写,可以给join 前头加上left/right关键字,为"左外连接"和"右外连接"

左外连接:

右外连接:

针对上述数据进行调整,使其不在"一一对应"

修该:

内连接:

左外连接:以左侧的表为基准(student join score,student为左侧表),保证左侧表每个数据一定会存在,左侧表数据在右侧表中不存在的部分(列),会使用NULL

右外连接:以右侧表为基准

以集合的角度来看待几种连接:

🏀自连接

同一个表,自己和自己计算笛卡尔积(自连接很少见到,属于处理特定问题的特殊技巧)

还是使用上述4张表(学生,班级,课程,分数)

  • 显示所有同一学生计算机原理成绩比Java成绩高的成绩信息

查看课程表和分数表之后,发现一个问题,score表在表示不同科目分数的时候,是通过不同的行来表示的,而前面进行各种的条件的查询,都是基于列和列之间进行比较,无法直接对行和行进行比较,注聚合查询是针对行和行之间的计算,而并非比较!!

需要把行之间的关系转为列之间的关系(自连接就可以完成这样的操作)

指定连接条件,精简一下:

指定连接条件,只显示左侧表课程id为3,右侧表课程id为1的数据:

显示计算机原理大于Java的成绩:

小结:可以把行之间的关系转为列之间的关系,但是自连接为了转换成上述列之间的关系,产生的大部分中间结果都是不必要的,对于体积比较大的表,自连接操作要慎用

🏀子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询(实际开发中,更要慎重使用)

  • 单行子查询:返回一行记录的子查询

案例:查询与"不想毕业" 同学的同班同学(还是上述4张表)

正常查询:

子查询:第一条sql语句写到第二条sql的条件中

  • 多行子查询:返回多行记录的子查询

案例为:查询"语文"或"英文"课程的成绩信息

使用[NOT] IN关键字:

🏀合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION 和UNION ALL时,前后查询的结果集中,字段需要一致。

  • union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行

案例:查询id小于3,或者名字为"英文"的课程:

  • union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

案例如下:

查询id小于3,或者名字为"Java"的课程

🌲MySQL增删改查总结

  • 数据库约束
  • 表的关系
  1. 一对一:
  2. 一对多:
  3. 多对多:需要创建中间表来映射两张表的关系
  • 新增

INSERT INTO table_name [(column [, column ...])] SELECT ...

  • 查询

聚合函数:MAX、MIN、AVG、COUNT、SUM

select ... from 表1,表2 where 条件

-- inner可以缺省

select ... from 表1 join 表2 on 条件 where 其他条件

分组查询:GROUP BY... HAVING ...

select ... from 表1 left/right join 表2 on 条件 where 其他条件

内连接

select ... from 表1,表2 where 条件

-- inner可以缺省

select ... from 表1 join 表2 on 条件 where 其他条件

外连接:

select ... from 表1,表1 where 条件

select ... from 表1 join 表1 on 条件

子查询:

-- 单行子查询

select ... from 表1 where 字段1 = (select ... from ...);

-- [NOT] IN

select ... from 表1 where 字段1 in (select ... from ...);

-- [NOT] EXISTS

select ... from 表1 where exists (select ... from ... where 条件);

-- 临时表:form子句中的子查询

select ... from 表1, (select ... from ...) as tmp where 条件

合并查询

-- UNION:去除重复数据

select ... from ... where 条件

union

select ... from ... where 条件

-- UNION ALL:不去重

select ... from ... where 条件

union all

select ... from ... where 条件

-- 使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

SQL查询中各个关键字的执行先后顺序: from > on> join > where > group by > with > having >select > distinct > order by > limit

相关推荐
sdaxue.com20 分钟前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
o(╥﹏╥)1 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
阿里嘎多学长1 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_1 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
Sunyanhui11 小时前
牛客网 SQL36查找后排序
数据库·sql·mysql
老王笔记2 小时前
MHA binlog server
数据库·mysql
lovelin+v175030409662 小时前
安全性升级:API接口在零信任架构下的安全防护策略
大数据·数据库·人工智能·爬虫·数据分析
DT辰白3 小时前
基于Redis的网关鉴权方案与性能优化
数据库·redis·缓存
2401_871213303 小时前
mysql高阶语句
数据库·mysql