SQL聚合函数核心是“对分组后数据整体计算”,需特别注意NULL处理(如COUNT(列名)忽略NULL、SUM/AVG静默跳过)、空表返回值差异(COUNT(*)=0,SUM=NULL)、GROUP BY合规性(非聚合字段须入GROUP BY)、HAVING与WHERE区别,以及用聚合组合快速诊断数据质量。

SQL聚合函数是面试中高频考点,重点不在死记语法,而在理解“对分组后的数据做整体计算”这一本质。SUM、AVG、COUNT看似简单,但常因NULL处理、空表、GROUP BY配合不当而出错。
COUNT的三种写法,结果可能完全不同
COUNT(*)统计行数,包括含NULL的行;COUNT(列名)只统计该列非NULL值的行数;COUNT(1)等价于COUNT(*),是优化写法而非“固定值计数”。
- 如果某列允许NULL,用COUNT(列名)会漏掉NULL行,比如统计“有手机号的用户数”,用COUNT(phone)就对,用COUNT(*)就错
- 空表时,COUNT(*)返回0,不是NULL;而SELECT SUM(age) FROM empty_table 返回NULL——这点常被忽略
- 别写COUNT(DISTINCT *),语法错误;DISTINCT只能作用于具体列或表达式
SUM和AVG对NULL的静默处理很危险
SUM和AVG自动跳过NULL值,不报错也不提醒。表面看没问题,实际可能掩盖数据质量问题。
- SUM(salary)在salary有20%为NULL时,结果只基于80%有效数据,但没人告诉你这个前提
- AVG(salary) = SUM(salary)/COUNT(salary),不是SUM(salary)/COUNT(*)。分子分母口径不一致,容易误读平均值含义
- 想把NULL当0参与计算?得显式写成SUM(COALESCE(salary, 0)),不能依赖默认行为
GROUP BY + 聚合函数,最容易踩的三个坑
面试题常让“查每个部门的平均工资”,一写就错,问题多出在SELECT列表和GROUP BY的匹配逻辑上。
- SELECT中所有非聚合字段,必须出现在GROUP BY子句中(MySQL 5.7+严格模式下报错,旧版可能返回随机值)
- 写SELECT dept_name, AVG(salary), MAX(name) —— MAX(name)无业务意义,且不同数据库返回结果不一致,属于典型错误用法
- HAVING过滤的是分组后结果,不是WHERE。比如“平均工资>5000的部门”,必须用HAVING AVG(salary) > 5000,写WHERE会报错
实战小技巧:一行代码判断数据分布
聚合函数组合使用,能快速发现异常。例如检查订单表金额是否合理:
- SELECT COUNT(*) 总单数, COUNT(amount) 有效金额单数, COUNT(*) - COUNT(amount) 缺失单数, AVG(amount) 平均金额 FROM orders
- 再加一个 MIN(amount), MAX(amount), STDDEV(amount) 就能看出是否有异常极大/极小值
- 用COUNT(CASE WHEN amount










