📊 SQL 入门 Day 4:聚合函数 — COUNT / SUM / AVG / MIN / MAX

📌 一句话总结

聚合函数对一组行进行计算并返回一个汇总值 ,是 SQL 做统计分析的基石。常与 GROUP BY 配对使用(今天的铺垫)。


1. 五大聚合函数一览

函数 作用 适用类型 NULL 处理
COUNT(*) 统计行数 任何 所有行都算
COUNT(column) 统计非 NULL 值个数 任何 剔除 NULL
SUM(column) 求和 数值 忽略 NULL
AVG(column) 求平均值 数值 忽略 NULL
MIN(column) 求最小值 数值/字符串/日期 忽略 NULL
MAX(column) 求最大值 数值/字符串/日期 忽略 NULL
sql 复制代码
-- 基础示例
SELECT
    COUNT(*) AS total_employees,
    COUNT(department_id) AS has_dept,        -- 比 COUNT(*) 少(有空部门)
    COUNT(DISTINCT department_id) AS unique_depts,  -- 去重统计
    AVG(salary) AS avg_salary,
    SUM(salary) AS total_salary,
    MIN(salary) AS min_salary,
    MAX(salary) AS max_salary
FROM employees;

2. NULL 的处理陷阱

sql 复制代码
-- 建测试表
CREATE TABLE scores (name TEXT, score INT);
INSERT INTO scores VALUES ('张三', 85), ('李四', NULL), ('王五', 92), ('赵六', NULL);

-- 不同 COUNT 的区别
SELECT
    COUNT(*)        AS total_rows,    -- 4(所有行)
    COUNT(score)    AS has_score,     -- 2(忽略 NULL)
    AVG(score)      AS avg_score,     -- 88.5((85+92)/2,不是 /4)
    SUM(score)/4    AS wrong_avg,     -- 44.25(千万别这么写)
    SUM(score)/COUNT(score) AS correct_avg  -- 88.5
FROM scores;

⚠️ AVG + NULL 的坑

AVG 内部是 SUM / COUNT(column)不是 SUM / COUNT(*)。如果行的 NULL 太多,算出来的平均值可能比预期高(因为分母变小了)。

sql 复制代码
-- 处理方式 1:把 NULL 视为 0
SELECT AVG(COALESCE(score, 0)) AS avg_including_zero FROM scores;
-- (85+0+92+0)/4 = 44.25

-- 处理方式 2:明确业务语义
-- "缺考"和"考了0分"是两回事,业务上通常是 方式1=实际平均 方式2=含缺考

3. DISTINCT 聚合

sql 复制代码
-- 去重统计
SELECT
    COUNT(DISTINCT city) AS unique_cities,
    SUM(DISTINCT salary) AS sum_unique_salaries  -- 不重复薪资之和(用得少)
FROM employees;

COUNT(DISTINCT col) 非常常用,「有多少种不同的值」。 SUM(DISTINCT col) 很罕见,只有在「每种值只算一次」的特殊业务才有用。


4. 聚合 + 条件过滤

三步走:WHERE 先过滤 → 再聚合。

sql 复制代码
-- 查询技术部的薪资统计
SELECT
    COUNT(*) AS tech_count,
    AVG(salary) AS tech_avg_salary
FROM employees
WHERE department = '技术部';

-- 多条件组合
SELECT
    COUNT(*) AS count_high_salary,
    AVG(salary) AS avg_high_salary
FROM employees
WHERE salary > 15000
  AND hire_date >= '2023-01-01';

WHERE vs HAVING(预告)

  • WHERE:在聚合前过滤行
  • HAVING:在聚合后过滤组
sql 复制代码
-- WHERE 过滤掉薪资为 NULL 的行再聚合
SELECT AVG(salary) FROM employees WHERE salary IS NOT NULL;
-- 上面等价于 SELECT AVG(salary) FROM employees;(AVG 本身就忽略 NULL)

5. 实战案例

案例 1:报表统计

sql 复制代码
-- 公司整体报表
SELECT
    COUNT(*) AS 员工总数,
    COUNT(CASE WHEN gender = '女' THEN 1 END) AS 女性人数,
    ROUND(AVG(salary), 0) AS 平均薪资,
    MAX(salary) AS 最高薪资,
    MIN(salary) AS 最低薪资,
    MAX(salary) - MIN(salary) AS 薪资差距
FROM employees;

案例 2:日期聚合

sql 复制代码
-- 最早和最晚入职日期
SELECT
    MIN(hire_date) AS 最早入职,
    MAX(hire_date) AS 最晚入职,
    DATEDIFF(MAX(hire_date), MIN(hire_date)) AS 公司历史天数  -- MySQL
FROM employees;

案例 3:数据质量检测

sql 复制代码
-- 检查各字段的完整性
SELECT
    COUNT(*) AS total,
    COUNT(email)     AS has_email,
    COUNT(phone)     AS has_phone,
    COUNT(department_id) AS has_dept,
    COUNT(salary)    AS has_salary
FROM employees;
-- has_email < total 说明有人没填邮箱

6. 聚合函数与非聚合列

sql 复制代码
-- ❌ 错误写法
SELECT name, AVG(salary) FROM employees;
-- name 是非聚合列,但有 100 行,AVG(salary) 只有 1 个值
-- 数据库不知道要显示哪个 name
-- MySQL 默认会取第一个 name(不报错但语义错误!)
-- PostgreSQL / SQLite 直接报错

-- ✅ 正确做法
SELECT AVG(salary) FROM employees;           -- 只查聚合
SELECT department_id, AVG(salary)            -- 加 GROUP BY
FROM employees
GROUP BY department_id;

⚠️ 规则: SELECT 中出现非聚合列,必须出现在 GROUP BY 中(MySQL 宽松模式除外,但不要依赖)。


📝 要点总结

函数 关键点
COUNT(*) 统计行数,含 NULL
COUNT(col) 统计非 NULL 行数
AVG(col) 忽略 NULL 后计算,分母不含 NULL
MIN/MAX 字符串按字典序,日期按时间序
NULL 所有聚合函数(除 COUNT(*))都忽略 NULL
DISTINCT COUNT(DISTINCT col) 去重计数
与非聚合列混用 必须配合 GROUP BY,否则语义错误
相关推荐
郑州光合科技余经理1 小时前
代驾系统架构拆解:订单链路、权限组织与私有化源码交付
开发语言·后端·算法·架构·系统架构·uni-app·php
hboot4 小时前
AI工程师第六课 - RAG检索增强生成
后端·langchain·llm
mldong4 小时前
jeeflow:98KB 的工作流引擎长什么样
后端
隔窗听雨眠7 小时前
AI重塑数据分析:从SQL执行者到智能基础设施构建者
人工智能·sql·数据分析
程序员cxuan7 小时前
速度太快了!本地可以跑 DeepSeek-V4-Flash 了
人工智能·后端·程序员
Yan_chen6668 小时前
SQL-LABS_Less18-20实战攻略
数据库·sql·web安全·网络安全
阿祖zu8 小时前
芝士就是力量!开源私有化部署与 GitHub 双向同步的个人知识笔记 App
前端·后端·ios
不才不才不不才8 小时前
Spring 源码系列(16): doDispatch 全流程——一次请求的主干链路
java·后端·spring
IT_陈寒9 小时前
SpringBoot自动配置失效?这个隐藏配置坑了我一整晚
前端·人工智能·后端
搜狐技术产品小编20239 小时前
告别“黑盒”与误判:如何用“多智能体对抗辩论”重构内容安全审核系统
后端·多agent