404 Not Found

404 Not Found


nginx

聚合函数

聚合函数

🌍 生活类比

想象你是一家超市的经理,面对一堆销售小票:

聚合函数就是SQL里的"计算器",帮你在大量数据中快速算出汇总结果


🎯 核心概念

COUNT — 计数

COUNT 用于统计行数。有两种常见写法:

SQL
-- COUNT(*):统计所有行(包含NULL行)
SELECT COUNT(*) AS total_employees FROM employees;

-- COUNT(列名):统计该列非NULL的行数
SELECT COUNT(email) AS has_email FROM employees;
写法 说明
COUNT(*) 统计所有行,不管是否有NULL
COUNT(列名) 只统计该列非NULL的行
COUNT(DISTINCT 列名) 统计该列去重后的非NULL行数

SUM — 求和

对数值列求总和,自动忽略NULL值。

SQL
SELECT SUM(salary) AS total_salary FROM employees;

AVG — 平均值

对数值列求平均,自动忽略NULL值(NULL不参与计算)。

SQL
SELECT AVG(salary) AS avg_salary FROM employees;

MAX / MIN — 最大值 / 最小值

找出列中的最大或最小值,自动忽略NULL值。

SQL
SELECT MAX(salary) AS highest, MIN(salary) AS lowest FROM employees;

聚合函数与 NULL 的行为

这是初学者最容易踩的坑:

函数 如何处理NULL
COUNT(*) NULL也计入(统计行数)
COUNT(列名) 忽略NULL
SUM(列名) 忽略NULL
AVG(列名) 忽略NULL(分母也不含NULL行)
MAX(列名) 忽略NULL
MIN(列名) 忽略NULL
SQL
-- 假设employees表有10行,其中email列有3个NULL
SELECT COUNT(*) AS total,        -- 10
       COUNT(email) AS has_email -- 7
FROM employees;
⚠️ 注意AVG 计算时,分母是非NULL的行数,不是总行数。如果5个员工中2人工资为NULL,AVG(salary) 只用3人的工资计算平均值。

DISTINCT 去重聚合

在聚合函数中使用 DISTINCT 可以先去重再聚合:

SQL
-- 有多少个不同的部门有员工?
SELECT COUNT(DISTINCT department_id) AS dept_count FROM employees;

-- 所有不同工资的总和(去重后求和)
SELECT SUM(DISTINCT salary) AS unique_salary_sum FROM employees;

📝 基本语法

SQL
-- 聚合函数基本语法
SELECT 聚合函数(列名) AS 别名
FROM 表名
WHERE 条件;

-- 多个聚合函数可以同时使用
SELECT COUNT(*) AS 总数,
       SUM(列名) AS 总和,
       AVG(列名) AS 平均,
       MAX(列名) AS 最大,
       MIN(列名) AS 最小
FROM 表名;

-- DISTINCT 去重聚合
SELECT COUNT(DISTINCT 列名) AS 去重计数
FROM 表名;
💡 提示

  • 聚合函数通常与 GROUP BY 配合使用(下一课学习),也可以单独使用(对全表聚合)
  • 聚合函数不能直接用在 WHERE 条件中,需要用 HAVING(后续学习)
  • NULL 在聚合运算中被自动跳过,这既是特性也是陷阱,务必注意

📌 示例

示例:统计员工基本信息

SQL
SELECT COUNT(*) AS 员工总数,
       COUNT(email) AS 有邮箱的人数,
       SUM(salary) AS 工资总额,
       AVG(salary) AS 平均工资,
       MAX(salary) AS 最高工资,
       MIN(salary) AS 最低工资
FROM employees;
▶ 试一试

输出:

TEXT
员工总数  有邮箱的人数  工资总额     平均工资    最高工资    最低工资
--------  -----------  ----------  ---------  ---------  ---------
8         7            112000.00   14000.00   20000.00   9000.00
💡 解读:8名员工中7人有邮箱(1人邮箱为NULL),平均工资14000。


示例:按条件聚合 + DISTINCT

SQL
-- 技术部有多少员工?有多少种不同的工资?
SELECT COUNT(*) AS 技术部人数,
       COUNT(DISTINCT salary) AS 不同工资数,
       AVG(salary) AS 技术部平均工资
FROM employees
WHERE department_id = 1;
▶ 试一试

输出:

TEXT
技术部人数  不同工资数  技术部平均工资
---------  ----------  -------------
3          3            17666.67
💡 解读:技术部3人,3种不同工资,平均工资17666.67。WHERE 先筛选出技术部的员工,再对筛选结果聚合。


示例:多个聚合函数 + 条件过滤

SQL
-- 订单金额统计:只统计已完成的订单
SELECT COUNT(*) AS 订单数量,
       SUM(total_amount) AS 总金额,
       AVG(total_amount) AS 平均订单金额,
       MAX(total_amount) AS 最大订单,
       MIN(total_amount) AS 最小订单
FROM orders
WHERE status = 'completed';
▶ 试一试

输出:

TEXT
订单数量  总金额      平均订单金额  最大订单    最小订单
-------  ----------  -----------  ---------  ---------
5        42500.00    8500.00      15000.00   2800.00
💡 解读WHERE 先过滤出已完成的订单,再对这些订单进行聚合计算。注意 WHERE 在聚合之前执行。


🎬 场景演练

场景一:HR报表——部门薪资概况

HR需要一份报表,了解公司整体薪资情况以及有多少员工有联系方式。

SQL
SELECT 
    COUNT(*) AS 总人数,
    COUNT(email) + COUNT(phone) AS 联系方式总数,
    SUM(salary) AS 年度工资支出,
    AVG(salary) AS 平均月薪,
    MAX(salary) - MIN(salary) AS 最大薪资差距
FROM employees
WHERE hire_date >= '2024-01-01';
💡 思路:先用 WHERE 筛选2024年以后入职的员工,再用多个聚合函数从不同维度汇总数据。

场景二:销售分析——订单价值分布

分析所有已发货订单的价值分布。

SQL
SELECT 
    COUNT(*) AS 已发货订单数,
    COUNT(DISTINCT customer_id) AS 不同客户数,
    SUM(total_amount) AS 总销售额,
    AVG(total_amount) AS 客单价,
    MAX(total_amount) AS 最大订单,
    MIN(total_amount) AS 最小订单
FROM orders
WHERE status = 'shipped';
💡 思路COUNT(DISTINCT customer_id) 帮助我们了解有多少不同的客户下过单,而不是订单数。


❓ 常见问题

Q:COUNT(*) 和 COUNT(1) 有区别吗? A: 在现代数据库中几乎没有区别,优化器会将它们处理为相同的执行计划。COUNT(*) 是更规范的写法,推荐使用。

Q:AVG遇到NULL怎么算? A: AVG 会忽略NULL值。假设5人中有2人工资为NULL,AVG(salary) 只用3人的工资计算,而不是除以5。如果想把NULL当作0计算,需要用 AVG(COALESCE(salary, 0))

Q:聚合函数能嵌套使用吗? A: 不能直接嵌套。比如 MAX(AVG(salary)) 会报错。要实现"找出平均工资最高的部门",需要用 GROUP BY + ORDER BY AVG(salary) DESC LIMIT 1,或者用子查询。

Q:SUM遇到空表会返回什么? A: SUMAVGMAXMIN 在空表或全为NULL时返回 NULL,而不是0。COUNT 返回0。如果需要返回0,用 COALESCE(SUM(列名), 0)


📖 小节

函数 作用 NULL处理 搭配DISTINCT
COUNT(*) 统计所有行 计入 不适用
COUNT(列) 统计非NULL行 忽略
SUM(列) 求和 忽略
AVG(列) 平均值 忽略(分母也不含)
MAX(列) 最大值 忽略
MIN(列) 最小值 忽略

📝 作业

作业1(⭐):查询 employees 表,统计总人数、最高工资、最低工资和平均工资。

作业2(⭐⭐):查询 orders 表,统计2025年的已完成订单数量、总金额和平均金额。要求:只计算 status = 'completed' 的订单。

作业3(⭐⭐⭐):查询 employees 表,统计每个薪资等级的人数。规则:工资 >= 15000 为"高薪",>= 10000 为"中等",其余为"初级"。提示:使用 CASE WHEN 配合聚合函数。


下一课

👉 14-group-by - 分组查询:学习 GROUP BY 分组查询,掌握按类别统计、HAVING 过滤分组等技能!

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏