当前位置: 首页 > news >正文

数据库基础知识——聚合函数、分组查询

目录

一、聚合函数

1.1 count

1.1.1 统计整张表中所有记录的总条数

1.1.2 统计单列的数据

1.1.3 统计单列记录+限制条件

1.2 sum

1.3 avg

1.4 max, min

二、group by 分组查询

2.1 语法

2.2 示例

2.3 having


一、聚合函数

常用的聚合函数

函数说明
count ([distinct] expr)返回查询到的数据的数量
sum ([distinct] expr)返回查询到的数据的总和,不是数字的没有意义
avg ([distinct] expr)返回查询到的数据的平均值,非数字无意义
max ([distinct] expr)返回查询到的数据的最大值,非数字无意义
min ([distinct] expr)返回查询到的数据的最小值,非数字无意义

1.1 count

mysql> select * from books;
+----+--------------------------+-----------+-------+-----------+---------------------+
| id | book_name                | author    | price | book_type | publish_date        |
+----+--------------------------+-----------+-------+-----------+---------------------+
| 29 | 阿波罗的秘密             | NULL      | 65.00 | NULL      | 2011-01-01 09:30:00 |
| 30 | 马达加斯加的企鹅         | 萨克斯    | 15.00 | NULL      | 2013-03-12 10:30:00 |
| 31 | 极简主义                 | NULL      | 32.00 | NULL      | 2019-04-28 00:50:00 |
| 32 | 另一种颜色               | NULL      | 32.50 | NULL      | 2019-10-01 07:10:00 |
| 33 | 夏日清泉                 | NULL      | 26.00 | NULL      | 2017-07-21 14:30:00 |
| 34 | NULL                     | NULL      | 34.00 | NULL      | 2014-06-01 11:11:00 |
| 35 | 冬日暖阳                 | 徐然      | 46.30 | NULL      | 2019-02-28 18:11:00 |
| 36 | 22岁                     | 桂芽紫    | 55.70 | NULL      | 2018-03-21 11:11:00 |
| 37 | 森林里有什么             | NULL      | 48.00 | NULL      | 2020-05-30 08:10:00 |
| 38 | 情书                     | NULL      |  NULL | NULL      | 2010-12-01 13:30:00 |
| 39 | 八音盒                   | switch    |  NULL | NULL      | 2021-06-15 15:20:00 |
| 40 | 灼烧的灵魂               | NULL      | 62.28 | NULL      | 2021-09-01 08:35:00 |
+----+--------------------------+-----------+-------+-----------+---------------------+
12 rows in set (0.01 sec)

1.1.1 统计整张表中所有记录的总条数

        ① 使用 * 做统计【推荐使用】

统计 books 表中有多少条记录:

mysql> select count(*) from books;
+----------+
| count(*) |
+----------+
|       12 |
+----------+
1 row in set (0.01 sec)

        ② 使用常量做统计

mysql> select count(1) from books;
+----------+
| count(1) |
+----------+
|       12 |
+----------+
1 row in set (0.00 sec)mysql> select count(100) from books;  # 任意常数,无实际意义
+------------+
| count(100) |
+------------+
|         12 |
+------------+
1 row in set (0.00 sec)

1.1.2 统计单列的数据

统计有多少本书标识了作者姓名

# 指定列做统计,null 值不被计入结果集中

mysql> select count(author) from books;
+---------------+
| count(author) |
+---------------+
|             4 |
+---------------+
1 row in set (0.00 sec)

1.1.3 统计单列记录+限制条件

统计价格小于40的图书数量

mysql> select count(*) from books where price < 40;
+----------+
| count(*) |
+----------+
|        5 |
+----------+
1 row in set (0.00 sec)mysql> select count(price) from books where price < 40;
+--------------+
| count(price) |
+--------------+
|            5 |
+--------------+
1 row in set (0.00 sec)

1.2 sum

# 只能统计单列数据类型为数值的列,并且值为 null 的数据行不参与统计

mysql> select sum(price) from books;
+------------+
| sum(price) |
+------------+
|     416.78 |
+------------+
1 row in set (0.00 sec)mysql> select sum(author) from books;
+-------------+
| sum(author) |
+-------------+
|           0 |
+-------------+
1 row in set, 4 warnings (0.00 sec)  # 统计非数值的列会发出警告信息mysql> show warnings;
+---------+------+-----------------------------------------------+
| Level   | Code | Message                                       |
+---------+------+-----------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '萨克斯'    |
| Warning | 1292 | Truncated incorrect DOUBLE value: '徐然'      |
| Warning | 1292 | Truncated incorrect DOUBLE value: '桂芽紫'    |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'switch'    |
+---------+------+-----------------------------------------------+
4 rows in set (0.00 sec)

1.3 avg

括号里面可以是单列数据,也可以是多列数据

-- 单列统计平均值
mysql> select avg(price) from books;
+------------+
| avg(price) |
+------------+
|  41.678000 |
+------------+
1 row in set (0.00 sec)-- 多列统计平均值
mysql> select * from game;
+------+-----------+---------+-------+--------------+--------------+
| id   | name      | lifebar | power | constitution | intelligence |
+------+-----------+---------+-------+--------------+--------------+
|    1 | 孙悟空    |     100 |   100 |          100 |           80 |
|    3 | 沙悟净    |     100 |    70 |           80 |           77 |
|    6 | 红孩儿    |     100 |    50 |          100 |           50 |
|    7 | 牛魔王    |     100 |    76 |           89 |           50 |
+------+-----------+---------+-------+--------------+--------------+
4 rows in set (0.00 sec)mysql> select avg(power+constitution+intelligence) as 总属性值 from game;
+--------------+
| 总属性值     |
+--------------+
|     230.5000 |
+--------------+
1 row in set (0.00 sec)

1.4 max, min

找出 game 表中 power 最高值和 intelligence 最低值

# 多个聚合函数可以同时被使用

mysql> select max(power),min(intelligence) from game;
+------------+-------------------+
| max(power) | min(intelligence) |
+------------+-------------------+
|        100 |                50 |
+------------+-------------------+
1 row in set (0.00 sec)

# 使用别名

mysql> select max(power) 最高力量值,min(intelligence) '最低智力值' from game;
+-----------------+-----------------+
| 最高力量值      | 最低智力值      |
+-----------------+-----------------+
|             100 |              50 |
+-----------------+-----------------+
1 row in set (0.00 sec)

# 同一列可以使用不同聚合函数

mysql> select max(power) 最高力量值,min(power) 最低力量值 from game;
+-----------------+-----------------+
| 最高力量值      | 最低力量值      |
+-----------------+-----------------+
|             100 |              50 |
+-----------------+-----------------+
1 row in set (0.00 sec)

二、group by 分组查询

        group by 子句的作用是通过⼀定的规则将⼀个数据集划分成若干个小的分组,然后针对若干个分组进行数据处理,比如使用聚合函数对分组进行统计。

2.1 语法

select {列 / 表达式}[,列 / 表达式...] 聚合函数(列 / 表达式) 
from 表名
group by {列 / 表达式}[,列 / 表达式...]
[having 条件]

{列 / 表达式}[,列 / 表达式...]:要查询的列或表达式,可以有多个,必须在 group by 子句中作为分组的依据;

聚合函数(列 / 表达式):列或者表达式如果不在 group by 子句中,则必须包含在聚合函数中。

2.2 示例

mysql> update books set book_type = '小说' where book_name = '阿波罗的秘密' or book_name = '另一种颜色' or book_name = '森林里有什么' or book_name = '灼烧的灵魂';
Query OK, 4 rows affected (0.07 sec)
Rows matched: 4  Changed: 4  Warnings: 0mysql> update books set book_type = '言情' where book_name = '情书' or book_name = '22岁' or book_name = '八音盒';
Query OK, 3 rows affected (0.06 sec)
Rows matched: 3  Changed: 3  Warnings: 0mysql> update books set book_type = '散文' where book_name = '夏日清泉' or book_name = '冬日暖阳' or book_name = 'null';
Query OK, 2 rows affected (0.06 sec)  # 影响行数只有两条,说明null并非字符串
Rows matched: 2  Changed: 2  Warnings: 0mysql> update books set book_type = '杂志' where book_name = '马达加斯加的企鹅' or book_name = '极简主义' or book_name = null;
Query OK, 2 rows affected (0.07 sec)  # 影响行数只有两条,因为null的比较不能使用 =
Rows matched: 2  Changed: 2  Warnings: 0# null的比较应该使用 <=>
mysql> update books set book_type = '杂志' where book_name <=> null;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from books;
+----+--------------------------+-----------+-------+-----------+---------------------+
| id | book_name                | author    | price | book_type | publish_date        |
+----+--------------------------+-----------+-------+-----------+---------------------+
| 29 | 阿波罗的秘密             | NULL      | 65.00 | 小说      | 2011-01-01 09:30:00 |
| 30 | 马达加斯加的企鹅         | 萨克斯    | 15.00 | 杂志      | 2013-03-12 10:30:00 |
| 31 | 极简主义                 | NULL      | 32.00 | 杂志      | 2019-04-28 00:50:00 |
| 32 | 另一种颜色               | NULL      | 32.50 | 小说      | 2019-10-01 07:10:00 |
| 33 | 夏日清泉                 | NULL      | 26.00 | 散文      | 2017-07-21 14:30:00 |
| 34 | NULL                     | NULL      | 34.00 | 杂志      | 2014-06-01 11:11:00 |
| 35 | 冬日暖阳                 | 徐然      | 46.30 | 散文      | 2019-02-28 18:11:00 |
| 36 | 22岁                     | 桂芽紫    | 55.70 | 言情      | 2018-03-21 11:11:00 |
| 37 | 森林里有什么             | NULL      | 48.00 | 小说      | 2020-05-30 08:10:00 |
| 38 | 情书                     | NULL      |  NULL | 言情      | 2010-12-01 13:30:00 |
| 39 | 八音盒                   | switch    |  NULL | 言情      | 2021-06-15 15:20:00 |
| 40 | 灼烧的灵魂               | NULL      | 62.28 | 小说      | 2021-09-01 08:35:00 |
+----+--------------------------+-----------+-------+-----------+---------------------+
12 rows in set (0.00 sec)

统计每种类别的书的数量

mysql> select book_type 类型,count(*) 数量 from books group by book_type;
+--------+--------+
| 类型   | 数量   |
+--------+--------+
| 小说   |      4 |
| 杂志   |      3 |
| 散文   |      2 |
| 言情   |      3 |
+--------+--------+
4 rows in set (0.00 sec)

统计每种类别的平均售价,最高售价,最低售价

mysql> select book_type,avg(price),max(price),min(price) from books group by book_type;
+-----------+------------+------------+------------+
| book_type | avg(price) | max(price) | min(price) |
+-----------+------------+------------+------------+
| 小说      |  51.945000 |      65.00 |      32.50 |
| 杂志      |  27.000000 |      34.00 |      15.00 |
| 散文      |  36.150000 |      46.30 |      26.00 |
| 言情      |  55.700000 |      55.70 |      55.70 |
+-----------+------------+------------+------------+
4 rows in set (0.00 sec)

使用 round(数值, 小数点位数) 指定保留多少位小数点,并添加别名优化上面的语句:

mysql> select book_type,round(avg(price),2) 平均售价,max(price) 最高售价,min(price) 最低售价 from books group by book_type;
+-----------+--------------+--------------+--------------+
| book_type | 平均售价     | 最高售价     | 最低售价     |
+-----------+--------------+--------------+--------------+
| 小说      |        51.95 |        65.00 |        32.50 |
| 杂志      |        27.00 |        34.00 |        15.00 |
| 散文      |        36.15 |        46.30 |        26.00 |
| 言情      |        55.70 |        55.70 |        55.70 |
+-----------+--------------+--------------+--------------+
4 rows in set (0.00 sec)

group by 之后还能跟 order by 子句对获得的结果集进行排序:

mysql> select book_type,round(avg(price),2) 平均售价,max(price)最高售价,min(price) 最低售价 from books group by book_type order by 平均售价 desc;
+-----------+--------------+--------------+--------------+
| book_type | 平均售价     | 最高售价     | 最低售价     |
+-----------+--------------+--------------+--------------+
| 言情      |        55.70 |        55.70 |        55.70 |
| 小说      |        51.95 |        65.00 |        32.50 |
| 散文      |        36.15 |        46.30 |        26.00 |
| 杂志      |        27.00 |        34.00 |        15.00 |
+-----------+--------------+--------------+--------------+
4 rows in set (0.00 sec)

还能统计每个类别有多少本书:

mysql> select book_type,round(avg(price),2),max(price),min(price),count(*) from books group by book_type;
+-----------+---------------------+------------+------------+----------+
| book_type | round(avg(price),2) | max(price) | min(price) | count(*) |
+-----------+---------------------+------------+------------+----------+
| 小说      |               51.95 |      65.00 |      32.50 |        4 |
| 杂志      |               27.00 |      34.00 |      15.00 |        3 |
| 散文      |               36.15 |      46.30 |      26.00 |        2 |
| 言情      |               55.70 |      55.70 |      55.70 |        3 |
+-----------+---------------------+------------+------------+----------+
4 rows in set (0.00 sec)

如果我想对分组之后的结果集进行过滤,比如找出平均售价大于50,小于55的类别,用 where 语句是错误的,而应该使用 having 子句 ↓

2.3 having

having 子句必须跟在 group by 子句后面!

mysql> select book_type,round(avg(price),2) 平均售价,max(price)最高售价,min(price) 最低售价 from books group by book_type order by 平均售价 desc having avg(price) between 50 and 55;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'having avg(price) between 50 and 55' at line 1
mysql> select book_type,round(avg(price),2) 平均售价,max(price)最高售价,min(price) 最低售价 from books group by book_type having avg(price) between 50 and 55 order by 平均售价 desc;
+-----------+--------------+--------------+--------------+
| book_type | 平均售价     | 最高售价     | 最低售价     |
+-----------+--------------+--------------+--------------+
| 小说      |        51.95 |        65.00 |        32.50 |
+-----------+--------------+--------------+--------------+
1 row in set (0.07 sec)mysql> select book_type,round(avg(price),2) 平均售价,max(price)最高售价,min(price) 最低售价 from books group by book_type having avg(price) >= 50 and avg(price) <= 55 order by 平均售价 desc;
+-----------+--------------+--------------+--------------+
| book_type | 平均售价     | 最高售价     | 最低售价     |
+-----------+--------------+--------------+--------------+
| 小说      |        51.95 |        65.00 |        32.50 |
+-----------+--------------+--------------+--------------+
1 row in set (0.01 sec)

* where 子句用在 from 表名 之后,也就是分组之前,而 having 子句跟在分组 group by 之后。如果需求要求对真实数据进行过滤,同时也需要对分组的结果进行过滤,那么在合适的位置同时写 where 和  having 即可。

http://www.xdnf.cn/news/1471159.html

相关文章:

  • ResNet 迁移学习---加速深度学习模型训练
  • 瑞芯微RV1126目标识别算法Yolov8的部署应用
  • 关于kubernetes和docker版本的一些总结
  • 工业设备管理软件与AI_HawkEye智能运维平台_璞华大数据
  • 自定义格式化数据(BYOFD)(81)
  • Python快速入门专业版(五):从 print 到交互:Python 解释器与 IDLE 的基础使用
  • 如何在序列水平上简单分析一个新蛋白质序列(novel protein sequence)
  • AM J BOT | 黄芪稳健骨架树构建
  • 360° 拖动旋转的角度计算原理
  • LangChain: Memory
  • 嵌入式学习日记(41)串口
  • 数据库(基础操作)
  • 载流子寿命
  • 基于FPGA实现CRC校验码算法(以MODBUS中校验码要求为例)verilog代码+仿真验证
  • Python命令行选项(flags)解析
  • 漫画布局面板设计系统
  • 事务管理的选择:为何 @Transactional 并非万能,TransactionTemplate 更值得信赖
  • 从Java全栈到前端框架:一位程序员的实战之路
  • NestJS 整合 Redis 特性详解
  • 2025年统计与数据分析领域专业认证发展指南
  • [TryHackMe]Wordpress: CVE-2021-29447(wp漏洞利用-SSRF+WpGetShell)
  • harmony 中集成 tuanjie/unity
  • Leetcode每日一练--20
  • ESP-IDF串口中断接收
  • 概率论第二讲——一维随机变量及其分布
  • 广告投放全链路解析
  • B.50.10.01-消息队列与电商应用
  • PyInstaller完整指南:将Python程序打包成可执行文件
  • Nacos中yaml文件新增配置项不规范导致项目启动失败
  • 在 CentOS 上完整安装 Docker 指南