首页 > 数据库 >MySQL:复杂查询 (一)——聚合函数&分组查询&联合查询

MySQL:复杂查询 (一)——聚合函数&分组查询&联合查询

时间:2024-08-11 12:26:45浏览次数:10  
标签:1.1 MySQL 查询 过滤 分组 子句 select

目录

1、聚合查询

1.1 聚合函数

1.1.1 COUNT()

1.1.2 SUM()

1.1.3 AVG()

1.1.4 MAX(),MIN()

1.2 分组查询

1.2.1 GROUP BY子句

 1.2.1.1 round()

1.2.2 HAVING

1.2.3 示例

2、联合查询

2.1 ①取相关表笛卡尔积 

2.2 ②过滤无效数据

2.3 ③精简查询结果

2.3.1 表的别名

3、综合练习

3.1 问题一

3.2 问题二


1、聚合查询

聚合查询是针对某一列数据的行与行之间进行的运算。

而我们之前所学的表达式查询是针对某一行数据的列与列之间进行的运算。

简单来说,聚合查询是竖着的,表达式查询是横着的。

1.1 聚合函数

聚合函数是MySQL内置的函数,我们可按需调用。

1.1.1 COUNT()

count():返回表中记录的总行数。

  • 函数参数可传 *,表示根据任意一列计算行数(推荐)
  • 函数参数可传常量
  • 函数参数可传指定的列,表示根据这一列计算行数。
  • 注意:当所传参数为列时,若该列存在数值为NULL的行,则不将为NULL的行计算进行数中。

1.1.2 SUM()

sum():把查询结果中所有行的指定列的数据相加。

注意:

  • 列的数据类型必须为数值型,不能为字符型或日期型。
  • 若指定的列中有数值为NULL,则NULL视为无效数据不计算进列的和。(之前我们学到,不管什么数值与NULL进行运算,结果都为NULL,但是这里不同,是因为函数内部进行了处理)
  • 通过sum函数求得的结果的值,不受表中字段类型的约束。

1.1.3 AVG()

avg():计算所有行的指定列的平均数。

我们既可以计算列的平均值,也可以计算表达式的平均值:

我们同样可以给列或表达式别名:

1.1.4 MAX(),MIN()

max():返回所有行指定的列的最大值。

min():返回所有行指定的列的最小值。

注意:多个聚合函数可以同时使用:

注意:

  • 在使用关于运算的聚合函数时(比如sum、avg、max、min),只能用于计算数值类型的列。
  • 在使用聚合函数时,都可以结合之前所学的where、limit等子句

1.2 分组查询

1.2.1 GROUP BY子句

在select中使用group by子句可以对指定列进行分组查询。

需要满足:使用group by进行分组查询时,select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中。

这里创建了一个公司员工表单:

我们根据职位role进行分组,则select查询到结果集中的列只能是role或者是包含于聚合函数中的其他列:

注意:在SQL语句中,一定有着这样的执行顺序:先选表,再分组,再select查询,所以我们不能通过别名来分组

 1.2.1.1 round()

在上图中,我们可以看到,通过聚合函数计算所得的值小数点后有6位,我们可以通过round函数手动设置小数位数:

语法:round(聚合函数,n)  n为手动设置的小数位数

同样,我们可以根据实际需要后跟order和limit子句:

注意:order子句是select查询后执行的,所以可以使用别名进行排序。

1.2.2 HAVING

group by子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 where子句,而需要用 having

注意:having跟在group by子句后

查询平均薪资大于1w且小于2w的职位:

注意:having子句是在分组完成后执行的,此时还没有执行select子句,故不能使用别名进行过滤,否则报错。执行顺序如下:

这里需要注意where过滤与having过滤的区别:

  1. where跟在 from+表名 的后面,在选好表后就要进行过滤,过滤的是分组前的数据
  2. having子句跟在group by子句的后面,是对分组后的结果进行过滤
  3. where过滤的是表中每一行真实的数据
  4. having过滤的是分组后通过聚合函数计算出的结果,而并非表中真实存在的
  5. 根据实际需求,可结合where和having完成过滤操作

1.2.3 示例

示例一:查询每个职位的最高工资、最低工资和平均工资:

-- 查询每个职位的最高工资、最低工资和平均工资:
select role,round(avg(salary),2) 平均薪资,round(max(salary),2) 最高薪资,round(min(salary),2) 最低薪资 from emp group by role;

示例二:显示平均工资低于1500的职位和它的平均工资

-- 显示平均工资低于1500的职位和它的平均工资
select role,round(avg(salary),2) 平均薪资 from emp group by role having avg(salary) < 1500;

2、联合查询

在设计表时,为了消除表中字段的部分函数依赖、传递依赖,我们通常会对数据进行拆分,拆分为多个表后再经过建立主外键关系进行关系的关联。但是这样也产生了一些问题,就是我们在使用select查询数据时,查询出来的记录是不完整、不明确的,例如下图:

而我们可以通过联合查询,使数据更加完整、明确的展现出来:

联合查询也是在工作中最常用的查询。

如何通过联合查询查询结果呢?有以下几个步骤:

  1. 确定那几张表要参与查询,取这几张表的笛卡尔积(全排列):select * from 表1,表2;
  2. 根据表与表之间的主外键关系,确定过滤条件,过滤无效数据(可根据实际情况继续过滤)
  3. 通过指定列查询,精简结果集

2.1 ①取相关表笛卡尔积 

联合查询的第一步就是取要查询的相关表的笛卡尔积,笛卡尔积即数据的全排列,上文的学生表和班级的表的笛卡尔积为下图:

取笛卡尔积:select * from 表1,表2;

执行SQL取笛卡尔积:

2.2 ②过滤无效数据

获取的笛卡尔积中存在着大量无效数据,我们需要过滤掉这些数据。

联合的表之间必然存在主外键关系,通过主外键值过滤无效数据。判断子表外键值和主表主键值是否相等即可,保留相等的,过滤不相等的。

因为主外键字段存在于两个表中,所以我们应该使用 表名.字段 的形式,指定哪个表中的哪个字段:

2.3 ③精简查询结果

上图中,我们可以发现表中有好多个无用字段如:class_id、id,我们可以通过 select 表名.列名 的形式,抽取出有用的字段来精简查询结果,

注意:因为存在多个表,所以一定是 select  表名.列名 的形式,明确哪个表中的哪个字段!

2.3.1 表的别名

通过 表名.列明 的方式是必要的,但是使得书写的代码量增多,我们可以通过给表起别名的方式简化代码,我们可以在 from 表名 后给表起一个更加简短的别名,这样我们就这样在select和where子句中缩短表名长度:


3、综合练习

这里分别建好了4个表,大家简单瞄一眼即可:

班级表:

课程表:

成绩表:

学生表:

3.1 问题一

查询许仙同学的成绩:

根据题目可以推断出需要联合学生表和成绩表两个相关表,根据上文所讲过程,即可查询成功:

3.2 问题二

查询所有同学的总成绩和信息:

  1. 因为要查询成绩和学生信息,所以我们要将成绩表和学生表进行联合,并过滤掉无效数据
  2. 根据题目信息,因为要查询每人的总成绩,一个同学为一组,所以我们要进行分组,而分组我们要根据编号student.student_id进行分组,因为学生姓名可能会出现重名的现象
  3. 通过select,查询学号、姓名等学生信息字段,利用聚合函数计算每名学生总成绩


END

标签:1.1,MySQL,查询,过滤,分组,子句,select
From: https://blog.csdn.net/2401_83595513/article/details/141070313

相关文章

  • Docker简单使用MySQL
    前提安装好Docker下载Mysql镜像在这个网址搜索Mysql并选择合适的镜像https://hub.atomgit.com/详情页就有拉取镜像的命令查看Docker所有镜像​ dockerimages镜像重命名​ dockertag镜像id仓库:标签​ dockertag8a709252ac32mysql:5.7镜像启动(容器)dockerrun......
  • 【第1篇】mysql语句大全及用法
    【第1篇】mysql语句大全及用法【第1篇】mysql语句大全及用法1.创建数据库2.选择数据库3.创建数据表4.插入数据5.查询数据6.更新数据7.删除数据8.修改数据表结构10.删除索引11.创建视图12.删除视图13.创建存储过程14.调用存储过程15.创建触发器17.备份数据......
  • mysql基础知识
    MySql基础知识#1.创建数据库:createdatabasemydata;(你所要建的数据库名)2.使用数据库usemydata;(说明:在使用数据库的前一定要加这个use语句,否则会出现没有数据库被选择)3.查看所有数据库showdatabases;4.查看该数据库的所有的表名showtables;5.删除数据库......
  • mysql load data file 批量导入数据
    mysql大量数据导入记录工作需要将大量数据导入到mysql中,但是数据量很大且几十个文本数据,每次导入的数据量有限制,所以需要分批导入。为了快速导入记录下使用loaddatainfile方式。1.SQL入数据语句先将数据传入/var/lib/mysql/test/路径mysql>loaddatainfile"/var/li......
  • MYSQL导出数据和导入数据命令
    MYSQL导出数据和导入数据命令网上也很多,我还是记录一下在我的博客里面,自己好查看MYSQL导出数据命令1.导出整个数据库mysqldump-u用户名-h数据库IP地址-p密码数据库名>备份的名称.sql测试账号如下:数据库名:web_user数据库IP:192.168.8.110用户名:root密码:root导出整......
  • mysql优化-索引失效场景
    1.索引字段不独立索引字段进行了表达式计算事先计算好表达式的值,再传过来,避免在SQLwhere条件=的左侧做计算select*fromemployeeswhereemp_no+1=10003;select*fromemployeeswhereemp_no=10002;索引字段是函数的参数预先计算好结果,再传过来,在where条件的......
  • MySQL基础详解(2)
    文章目录多表查询MySQL函数数字函数字符串函数日期函数高级函数使用Python操作MySQL1、安装第三方模块pymysql2、操作MySQLMySQL中的多表查询是数据库操作中非常常见且重要的一个环节,多表查询是数据库查询中非常强大的功能,能够让你根据需要从多个表中提取和组合数......
  • MySQL基础详解(1)
    文章目录Sql1.什么是Sql2、SQL通用语法3、SQL分类DDL:操作数据库、表3.1操作数据库:CRUD3.2操作表CRUDDML:增删改表中数据1.添加数据:2.删除数据:3.修改数据:DQL:查询表中的记录1.语法:2.基础查询3.条件查询4.排序查询其他函数5.聚合函数6.分组查询7.分页查询:DCL:管理用户......
  • MySQL的安装
    文章目录在线安装方式离线安装方式1、卸载已有的MySQL文件2、安装mysql3、后续命令修改字符集MySQL是一种开源的关系型数据库管理系统(RDBMS),由瑞典MySQLAB公司开发,后来被SunMicrosystems收购,并最终归属于Oracle公司。MySQL因其高性能、可靠性、扩展性和安全性而广......
  • MySQL高级知识-----Explain
    Explainexplain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。explain主要用于分析查询语句或表结构的性能瓶颈。1.explain的作用通过explain+sql语句可以知道如下内容:1.表的读取顺序。(对应id)......