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

SQL:聚合函数(Aggregate Functions)

目录

第一性原理出发思考 ——我们为什么需要聚合函数?

什么是聚合函数? 

常见聚合函数 + 实例讲解 

 🔸 1. COUNT() —— 计数

 🔸 2. MAX() / MIN() —— 最大 / 最小值

🔸 3. SUM() —— 求和 

🔸 4. AVG() —— 平均值 

 GROUP BY

GROUP BY 是什么? 

执行逻辑 

 GROUP BY 的重要规则

HAVING

为什么还要 HAVING? 

HAVING 是什么? 

实例讲解 

HAVING 和 WHERE 的区别 

思维图:GROUP BY + HAVING 工作流程 

第一性原理出发思考 ——我们为什么需要聚合函数?

在数据库中,查询的本质是从一堆数据中“找出我们需要的信息”。有时候我们不仅想看到“每一行”,而是想对一整列进行“汇总”,比如:

  • 一共预订了多少场电影?

  • 哪个用户最爱看电影?

  • 每部电影平均有多少人观看?

这个时候,我们就需要——聚合函数

什么是聚合函数? 

聚合函数是 MySQL 中用于对一整列的数据进行统计、计算或汇总的函数。它不是作用于“某一行”,而是作用于“一列”或“一组”数据。 


常见聚合函数 + 实例讲解 

我们来建一个简单的工资表 employees,字段如下: 

CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),salary INT
);

插入一些数据: 

INSERT INTO employees (name, salary) VALUES 
('Alice', 5000),
('Bob', 6000),
('Charlie', 5500),
('Diana', 7000),
('Eve', 6500),
('Frank', 5200);

 🔸 1. COUNT() —— 计数

SELECT COUNT(*) FROM employees;

 我们给数据库一个表,它扫描所有行,每遇到一行就 +1,最后告诉你一共有几行数据。

最后返回 6

SELECT COUNT(salary) FROM employees;

 与 COUNT(*) 类似,但如果有 NULL 工资的员工,不计入。

 🔸 2. MAX() / MIN() —— 最大 / 最小值

SELECT MAX(salary), MIN(salary) FROM employees;

 数据库扫描每一个值,记录当前最大/最小值,直到最后一行。

最后返回:MAX: 7000, MIN: 5000 

🔸 3. SUM() —— 求和 

SELECT SUM(salary) FROM employees;

 我们把这一列的值都加起来,输出总和。适合处理“总销售额”、“总时长”等问题。

最后返回:5000 + 6000 + 5500 + 7000 + 6500 + 5200 = 35,200
 

🔸 4. AVG() —— 平均值 

SELECT AVG(salary) FROM employees;

 就是 SUM(salary) / COUNT(salary),把总量除以人数,得到“人均”指标。

最后返回:35200 / 6 = 5866.67 

你还可以这样玩: 

-- 所有工资加 500 后的平均值是多少?
SELECT AVG(salary + 500) FROM employees;-- 平均名字长度(字符串函数 + 聚合函数)
SELECT AVG(CHAR_LENGTH(name)) FROM employees;

 GROUP BY

我们之前讲的聚合函数是对“一整列”做统计,但很多时候,我们想知道: 

各个部门的平均工资分别是多少? 

这就需要把“整张表”按部门拆成若干小组,每一组内部再用聚合函数统计。 

💡 这时候,我们就需要 GROUP BY。 

GROUP BY 是什么? 

GROUP BY 是 SQL 中的“分组器”

它把一张大表,按某个字段(或字段组合)划分成一组组数据,然后对每组单独使用聚合函数。 

执行逻辑 

🎯 目标:统计各个部门的平均工资 

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;

这条 SQL 的背后逻辑是这样的:

  1. 扫描整张表

  2. department 字段的值,把表划分为若干组:

    • HR: [Alice, Charlie, Frank]

    • IT: [Bob, Diana]

    • Finance: [Eve]

  3. 对每组单独执行 AVG(salary)

  4. 输出每组的 department 和对应的 avg_salary

执行结果:

departmentavg_salary
HR5233.33
IT6500.00
Finance6500.00

 GROUP BY 的重要规则

规则说明
SELECT 中非聚合字段必须出现在 GROUP BY 中除非是聚合函数计算的,否则 SELECT 中的字段必须被 GROUP BY
GROUP BY 后面可以接多个字段表示按多个维度进行分组
整张表 → 按字段值分组 → 每组做聚合 → 输出每组统计结果

HAVING

为什么还要 HAVING? 

我们已经知道:每个部门的平均工资。但问题来了: 

❓“只想要平均工资大于 6000 的部门”怎么办? 

你可能第一反应是: 

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 6000     -- 🚫 错误用法
GROUP BY department;

 ❌ 错误!
因为 WHERE 是在分组之前起作用的,根本没法识别 AVG(salary) 这种“分组后的值”。

HAVING 是什么? 

HAVING 是用来 过滤分组后的结果 的

它和 WHERE 类似,但发生在 GROUP BY 之后 

实例讲解 

🎯 问题:找出平均工资高于 6000 的部门 

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 6000;

🔍 数据回顾(之前的平均工资):

departmentavg_salary
HR5233.33
IT6500.00
Finance6500.00

📌 这条 SQL 会返回:

departmentavg_salary
IT6500.00
Finance6500.00

因为只有这两个部门的平均工资大于 6000。

🔹 统计每个部门人数大于 2 的部门:

SELECT department, COUNT(*) AS num_employees 
FROM employees 
GROUP BY department 
HAVING COUNT(*) > 2;

🔹 平均工资等于最大工资的部门

SELECT department, AVG(salary), MAX(salary) FROM employees 
GROUP BY department 
HAVING AVG(salary) = MAX(salary);

 使用别名:

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 6000;   -- ✅ 正确用法

HAVING 和 WHERE 的区别 

语句部分用途作用顺序(谁先执行)
WHERE筛选原始数据在分组之前执行
HAVING筛选分组结果在分组之后执行

 WHERE 是筛选行,HAVING 是筛选组。

WHERE 是先手,HAVING 是后手。

思维图:GROUP BY + HAVING 工作流程 

原始表↓   (WHERE)
过滤掉不满足条件的行↓   (GROUP BY)
按照字段分组↓   (聚合函数)
计算每组的结果↓   (HAVING)
筛选掉不满足条件的组↓   (SELECT)
最终展示结果
http://www.xdnf.cn/news/89.html

相关文章:

  • 10-openwrt-one调整rootfs_data卷,新增fit2、log、plugins等卷
  • 【MySQL】MySQL表的增删改查(CRUD) —— 上篇
  • MCP 协议:AI 世界的 “USB-C 接口”,开启智能交互新时代
  • PyTorch 深度学习实战(37):分布式训练(DP/DDP/Deepspeed)实战
  • UE5编辑器静止状态下(非 Play 模式)睫毛和眼睛的渲染是正常的,而在 Play 模式下出现模糊
  • Thin-Agent服务(TAS)概述
  • 机器学习在催化剂设计中的应用理论加实操
  • 扫雷-C语言版
  • Linux系统编程学习 day4 进程
  • 深入理解 VMware 虚拟机网络模式:为虚拟化管理铺平道路
  • 【Python爬虫基础篇】--1.基础概念
  • 鸿蒙系统开发中路由使用详解
  • Unity URP Moblie AR示例工程,真机打包出来,没阴影
  • 秘密任务 2.0:如何利用 WebSockets + DTOs 设计实时操作
  • OpenHarmony Camera开发指导(五):相机预览功能(ArkTS)
  • 【JavaWeb】详细讲解 HTTP 协议
  • Linux,redis群集模式,主从复制,读写分离
  • Tomcat
  • HTTP 2.0 协议特性详解
  • LeetCode每日一题4.17
  • C#日志辅助类(Log4Net)实现
  • Python学习笔记
  • jenkins凭据管理(配置github密钥)
  • ssh用户秘钥登录设置
  • ReadableStream响应主体数据处理(截图自用)
  • 第七章:7.2求方程a*x*x+b*x+c=0的根,用3个函数,分别求当:b*b-4*a*c大于0、等于0和小于0时的根并输出结果。从主函数输入a、b、c的值
  • 聊一聊接口测试是如何进行的?
  • 16位海明码解码电路设计教程
  • 压缩包网页预览(zip-html-preview)
  • java IO/NIO/AIO