count(*)统计所有行数,count(字段)仅统计该字段非null的行;sum和avg自动忽略null,但全null时返回null;where不能用聚合函数,having可以,执行顺序为from→where→group by→having→select→order by。

COUNT、SUM、AVG 是 SQL 中最常用也最容易被误解的三个聚合函数,面试中常考的不是语法本身,而是它们对 NULL 的处理逻辑、与 GROUP BY 的配合方式,以及在 WHERE/HAVING 中的使用边界。
COUNT(*) 和 COUNT(字段) 的本质区别
COUNT(*) 统计的是行数,不管任何列是否为 NULL;而 COUNT(字段) 只统计该字段值非 NULL 的行数。这是高频踩坑点。
- 如果某列允许 NULL,且实际存在空值,COUNT(字段) 会比 COUNT(*) 小
- COUNT(1) 和 COUNT(*) 在绝大多数数据库中执行效果一致,都是按行计数,不关心内容
- 想统计“有订单的用户数”,用 COUNT(user_id);想统计“所有订单记录条数”,用 COUNT(*)
SUM 和 AVG 自动跳过 NULL,但结果可能意外为 NULL
SUM 和 AVG 都会忽略 NULL 值参与计算——这点和 COUNT(字段) 类似。但要注意:当分组内所有值都是 NULL,或整张表无数据时,SUM 和 AVG 返回 NULL,不是 0。
- 需要确保结果不为 NULL,可配合 COALESCE(SUM(amount), 0) 使用
- AVG(0, NULL, 0) 结果是 0,因为只对两个 0 计算平均值;AVG(NULL, NULL) 结果是 NULL
- 不要在 WHERE 子句中写 AVG(score) > 80 —— 聚合函数不能直接用于 WHERE,得用 HAVING
WHERE、GROUP BY、HAVING 的执行顺序决定能写什么
SQL 执行顺序是:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。这意味着:
- WHERE 过滤的是原始行,不能用 SUM、AVG 等聚合结果做条件
- HAVING 过滤的是分组后的结果,可以写 HAVING AVG(score) >= 60
- SELECT 中的别名(如 AVG(score) AS avg_score)在 HAVING 中通常可用,但在 WHERE 中一定不可用
常见组合题型:分组统计 + 条件过滤 + 空值容错
例如:“查每个部门的平均工资,排除工资为 NULL 的员工,且只显示平均工资超过 8000 的部门”。
- 必须用 GROUP BY dept_id
- WHERE salary IS NOT NULL 排除空工资(在分组前过滤,效率更高)
- HAVING AVG(salary) > 8000 对分组后结果筛选
- 建议加上 COALESCE(AVG(salary), 0) 防止某部门全为 NULL 导致结果异常










