AVG()函数计算非NULL值的算术平均值,自动跳过NULL记录;整列全NULL时返回NULL,不可误作0处理,需用COALESCE显式转换。

AVG() 函数的基本用法和 NULL 处理逻辑
AVG() 只计算非 NULL 值,自动跳过该列中所有 NULL 记录。这不是“忽略缺失”,而是 SQL 标准定义的行为——它先过滤 NULL,再对剩余值求算术平均。如果你误以为 AVG() 会把 NULL 当作 0 参与计算,结果一定会偏低。
- 写
SELECT AVG(price) FROM products;时,price IS NULL的行完全不参与分母和分子运算 - 若整列全为
NULL,AVG()返回NULL,不是 0,也不是报错 - 想把
NULL当 0 算?得显式转换:AVG(COALESCE(price, 0)),但要清楚这改变了统计意义
GROUP BY 场景下 AVG() 的常见陷阱
在分组聚合中,AVG() 很容易被误用成“每组平均后再全局平均”——这是错误的。SQL 中 AVG() 在 GROUP BY 后是按组独立计算的,不会自动加权。
- 正确:统计每个部门的平均薪资 ——
SELECT dept, AVG(salary) FROM employees GROUP BY dept; - 错误:试图用
AVG(AVG(salary))求“部门均值的均值”,语法不合法,且逻辑错误(忽略了部门人数权重) - 若真需要加权平均(比如大部门拉高整体感),得手动算:
SUM(salary) / SUM(1)或用AVG()配合窗口函数
AVG() 和数据类型的关系必须留意
AVG() 的返回类型取决于输入列:对整数列(如 INT)默认返回带小数的数值类型(如 DECIMAL 或 FLOAT),但精度可能意外丢失,尤其在老版本 MySQL 或某些嵌入式数据库中。
- PostgreSQL 和 SQL Server 通常返回
NUMERIC,保留足够小数位 - MySQL 5.7 对
INT列的AVG()默认返回DOUBLE,可能有浮点误差;可用ROUND(AVG(col), 2)控制显示 - 如果列是
TEXT或字符串型数字(如'123'),多数数据库会隐式转,但 SQLite 可能直接返回 0 或报错,务必先CAST(col AS REAL)
替代方案:什么时候不该用 AVG()?
当数据存在明显偏态、异常值或业务要求“典型值”而非数学均值时,AVG() 反而会掩盖真实分布。这时候中位数(MEDIAN())更合适,但注意:MEDIAN() 不是 SQL 标准函数,各数据库支持差异大。
- PostgreSQL 有
PERCENTILE_CONT(0.5)可模拟中位数 - MySQL 8.0+ 可用窗口函数 + 行号逼近,但写法冗长
- 简单去极值?可结合
WHERE过滤:AVG(price) WHERE price BETWEEN (q1) AND (q3) - 空表或无匹配行时,
AVG()返回NULL,应用层需判断,别直接转 float 导致空指针

















