avg()函数自动忽略null值,仅对非null数值计算平均值;遇非数值类型会报错,分组时需确保非聚合字段均出现在group by中,结果精度由输入列类型决定。

AVG() 函数能直接算出数值列的平均值,但遇到 NULL、非数值类型或分组逻辑时,结果会出人意料——不是函数不对,而是你没控制好输入。
AVG() 只对非 NULL 数值生效
它自动跳过 NULL 值,但不会跳过字符串、日期或空字符串。如果列里混了 'abc' 或 '',多数数据库(如 MySQL)会在隐式转换失败时报错;PostgreSQL 则直接拒绝计算。
- 先确认列类型:
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'price' AND TABLE_NAME = 'orders'; - 检查脏数据:
SELECT price FROM orders WHERE price IS NOT NULL AND price::text !~ '^[0-9.+-eE]+$';(PostgreSQL 示例) - 安全兜底写法:
AVG(CAST(price AS NUMERIC)) FILTER (WHERE price ~ '^[0-9.+-eE]+$')(PostgreSQL),MySQL 可用AVG(CAST(price AS DECIMAL))配合WHERE price REGEXP '^[0-9.+-eE]+$'
GROUP BY 下 AVG() 的行为容易被误解
不加 GROUP BY 时,AVG() 返回整张表的单个值;一旦加了 GROUP BY,它就按每组单独计算——但很多人忘了,SELECT 列表里所有非聚合字段都必须出现在 GROUP BY 中,否则报错(如 PostgreSQL、SQL Server)或返回不确定结果(如旧版 MySQL)。
- 正确写法:
SELECT category, AVG(price) FROM products GROUP BY category; - 想同时查最大值和平均值?必须都写进 SELECT:
SELECT category, AVG(price), MAX(price) FROM products GROUP BY category; - 若只想看某类别的平均值,别用 GROUP BY,改用 WHERE:
SELECT AVG(price) FROM products WHERE category = 'electronics';
AVG() 结果精度和类型取决于输入列
输入是 INT,结果默认仍是整数(MySQL 会截断小数部分;PostgreSQL 保留小数但精度可能低)。这不是 bug,是类型推导规则。
- 强制高精度:
AVG(CAST(score AS DECIMAL(10,2))) - 避免整数除法陷阱(如 SQLite):
AVG(CAST(duration_ms AS REAL)) - 注意浮点误差:对金额类字段,优先用
DECIMAL类型存储,再算AVG(),别依赖FLOAT
最常被忽略的是数据清洗环节——AVG() 不会告诉你哪一行拖了后腿,它只默默吞掉 NULL,然后对剩下所有“看起来像数”的值做算术平均。真要可信,得先用 COUNT(*) 和 COUNT(column) 对比,确认缺失比例;再用条件过滤剔除异常文本。










