【MySQL新手到通关】第七章 聚合函数使用详解

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 0. 前置为了方便测试,我们导入一些数据

0. 前置


为了方便测试,我们导入一些数据

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for procatch_work_om_sp_type
-- ----------------------------
DROP TABLE IF EXISTS `procatch_work_om_sp_type`;
CREATE TABLE `procatch_work_om_sp_type`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `sp_type_name` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '备件类型名称',
  `sp_type_parent_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '父类类型id 没有就是0',
  `current_level` tinyint(3) UNSIGNED NOT NULL COMMENT '当前层级(1/2/3)',
  `sp_num` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '该备件类型下的备件数量(只是该备件类型下,不算类型父级)',
  `create_time` datetime(0) DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1661945101694476291 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '运维-备件-备件类型' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of procatch_work_om_sp_type
-- ----------------------------
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810442107748353, '五金', 0, 1, 0, '2023-04-17 11:53:18');
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810699784814593, '通用五金配件', 1647810442107748353, 2, 1, '2023-04-17 11:54:20');
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810699793203202, '装饰五金配件', 1647810442107748353, 2, 21, '2023-04-17 11:54:20');
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810699797397506, '五金冲压配件', 1647810442107748353, 2, 0, '2023-04-17 11:54:20');
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810699805786113, '相框五金配件', 1647810442107748353, 2, 0, '2023-04-17 11:54:20');
INSERT INTO `procatch_work_om_sp_type` VALUES (1647810699814174722, '门窗五金配件', 1647810442107748353, 2, 0, '2023-04-17 11:54:20');
INSERT INTO `procatch_work_om_sp_type` VALUES (1648249529373491202, '铣床', 0, 1, 0, '2023-04-18 16:58:05');
INSERT INTO `procatch_work_om_sp_type` VALUES (1648249529377685506, '机床', 0, 1, 8, '2023-04-18 16:58:05');
INSERT INTO `procatch_work_om_sp_type` VALUES (1648249529381879810, '钻床', 0, 1, 0, '2023-04-18 16:58:05');

数据如下

8a04f1892505443ba2167353be3d0564.png

1. 聚合函数介绍


什么是聚合函数

聚合函数作用于一组数据,并对一组数据返回一个值。


346f7c02ed164b2c9a3370e5bede4251.png

聚合函数类型

  • AVG() 求平均值
  • SUM() 求和
  • MAX() 求最大值
  • MIN() 求最小值
  • COUNT() 求总行数

聚合函数语法

SELECT SUM(某字段) FROM TABLE_NAME WHERE ...

聚合函数不能嵌套调用。比如不能出现类似“AVG(SUM(字段名称))”形式的调用。


1.1 AVG 和 SUM 函数

可以对数值型数据使用 AVGSUM 函数。

AVG 比如我们求案例表的全部备件类型下的备件数量的平均值

SELECT AVG(sp_num) FROM `procatch_work_om_sp_type`


结果如下

01fa6d58ddd749baaaf41a2654186c8b.png

SUM 比如我们求案例表的全部备件类型下的备件数量的

SELECT SUM(sp_num) FROM `procatch_work_om_sp_type`

结果如下

2ac6f814a6ca49238fb2df44999591e4.png

1.2 MIN 和 MAX 函数


可以对任意数据类型的数据使用 MINMAX 函数。

比如我们求案例表的全部备件类型下的备件数量的最小值、最大值

SELECT MIN(sp_num),MAX(sp_num) FROM `procatch_work_om_sp_type`

结果如下

3b18dce59e874554a9ecd147aefdc08c.png

1.3 COUNT函数


COUNT(*) 返回表中记录总数,适用于任意数据类型。

COUNT(expr) 返回expr不为空的记录总数。

比如我们有如下这张表:

32cdefe8d9334dc484118bd1e494f827.png

执行如下语句

SELECT COUNT(*), COUNT(name) FROM `agreement_file`

得到结果:分别为 46 个 29

5e1efb3f8a8f4343bfcc2839958ce39a.png

COUNT(*) 返回表中记录总数 :46 。

COUNT(name) 返回 name 不为空的记录总数 :29。

问题:用count(*),count(1),count(列名)谁好呢?

- 其实,对于MyISAM引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。
- Innodb引擎的表用count(*),count(1)直接读行数,复杂度是O(n),因为innodb真的要去数一遍。
但好于具体的count(列名)。

问题:能不能使用count(列名)替换count(*)?

- 不要使用 count(列名)来替代 count(*) , count(*) 是 SQL92 定义的标准统计行数的语法,跟数
据库无关,跟 NULL 和非 NULL 无关。
- 说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

2. GROUP BY


2.1 基本使用

3c527a4fc65c451dbb5c41586885d4af.png

可以使用GROUP BY 语句将表中的数据分成若干组 展示每个备件类型的个数

SELECT spare_part_type_id, SUM(1) 
FROM `procatch_work_om_spare_part` 
GROUP BY spare_part_type_id

0d2dd00ace8f4f91895db41ed26f9675.png

3. HAVING


3.1 基本使用

过滤分组:HAVING子句

1. 行已经被分组。

2. 使用了聚合函数。

3. 满足HAVING 子句中条件的分组将被显示。

4. HAVING 不建议单独使用,建议只和 GROUP BY 一起使用。

330ce4058b5f468f9c96cc90518cdc54.png

注意:不能在 WHERE 子句中使用聚合函数


3.2 WHERE和HAVING的对比


区别1WHERE 可以直接使用表中的字段作为筛选条件,但不能使用分组中的计算函数作为筛选条件;HAVING 必须要与 GROUP BY 配合使用,可以把分组计算的函数和分组字段作为筛选条件。这决定了,在需要对数据进行分组统计的时候,HAVING 可以完成 WHERE 不能完成的任务。这是因为,在查询语法结构中,WHERE 在 GROUP BY 之前,所以无法对分组结果进行筛选。HAVING 在GROUP BY 之后,可以使用分组字段和分组中的计算函数,对分组的结果集进行筛选,这个功能是WHERE 无法完成的。另外,WHERE排除的记录不再包括在分组中。



区别2:如果需要通过连接从关联表中获取需要的数据,WHERE 是先筛选后连接,而 HAVING 是先连接后筛选。 这一点,就决定了在关联查询中,WHERE 比 HAVING 更高效。因为 WHERE 可以先筛选,用一个筛选后的较小数据集和关联表进行连接,这样占用的资源比较少,执行效率也比较高。HAVING则需要先把结果集准备好,也就是用未被筛选的数据集进行关联,然后对这个大的数据集进行筛选,这样占用的资源就比较多,执行效率也较低。


小结如下

优点 缺点
WHERE 先筛选数据再关联,执行效率高 不能使用分组中的计算函数进行筛选
HAVING 可以使用分组中的计算函数 在最后的结果集中进行筛选,执行效率较低


开发中的选择:

WHERE 和 HAVING 也不是互相排斥的,我们可以在一个查询里面同时使用 WHERE 和 HAVING。包含分组统计函数的条件用 HAVING,普通条件用 WHERE。这样,我们就既利用了 WHERE 条件的高效快速,又发挥了 HAVING 可以使用包含分组统计函数的查询条件的优点。当数据量特别大的时候,运行效率会有很大的差别。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
SQL 关系型数据库 MySQL
mysql子查询、聚合函数
mysql子查询、聚合函数
|
5月前
|
关系型数据库 MySQL 数据挖掘
轻松入门MySQL:深入理解MySQL聚合函数,实战进销存项目中的应用与技巧(8)
轻松入门MySQL:深入理解MySQL聚合函数,实战进销存项目中的应用与技巧(8)
|
5月前
|
关系型数据库 MySQL 数据库
MySQL查询聚合函数与分组查询
MySQL查询聚合函数与分组查询
|
26天前
|
SQL 关系型数据库 MySQL
MySQL:表的设计原则和聚合函数
本文详细介绍了数据库表设计的原则与范式,包括从需求中找到实体及其属性,确定实体间关系,并使用SQL创建具体表。文章还深入探讨了一范式、二范式和三范式的要求及不满足这些范式时可能遇到的问题。此外,文中通过实例解释了一对一、一对多和多对多关系的表设计方法,并介绍了如何使用聚合函数如 COUNT()、SUM()、AVG()、MAX() 和 MIN() 进行数据统计和分析。最后,文章还展示了如何通过 SQL 语句实现数据的复制和插入操作。
40 7
MySQL:表的设计原则和聚合函数
|
2月前
|
SQL 存储 关系型数据库
|
3月前
|
关系型数据库 MySQL 数据挖掘
MySQL 聚合函数案例解析:深入实践与应用
MySQL 聚合函数案例解析:深入实践与应用
|
3月前
|
SQL 关系型数据库 MySQL
MySQL 聚合函数深入讲解与实战演练
MySQL 聚合函数深入讲解与实战演练
|
5月前
|
SQL 关系型数据库 MySQL
【MySQL进阶之路 | 基础篇】MySQL之聚合函数与应用
【MySQL进阶之路 | 基础篇】MySQL之聚合函数与应用
【MySQL进阶之路 | 基础篇】MySQL之聚合函数与应用
|
4月前
|
关系型数据库 MySQL Windows
14. Mysql 开窗函数,一文带你直接通关
14. Mysql 开窗函数,一文带你直接通关
381 0
|
4月前
|
SQL 关系型数据库 MySQL
MySQL数据库——SQL(3)-DQL(基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询、案例练习)
MySQL数据库——SQL(3)-DQL(基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询、案例练习)
51 0
下一篇
无影云桌面