AVG()跳过NULL导致分母缩小为COUNT(score)而非COUNT(),静默引入偏差;COALESCE(score,0)语义污染将“未知”误作“零值”;空结果返回NULL易致应用崩溃;GROUP BY中须并列输出AVG、COUNT(score)和COUNT()以校验数据完整性。

AVG()自动跳过NULL,但分母变小了
AVG(score) 的实际计算逻辑是 SUM(score) / COUNT(score),不是除以总行数 COUNT(*)。只要某行 score 为 NULL,它既不参与求和,也不参与计数——分母悄悄缩水了。
比如 10 条记录里有 3 条 score IS NULL,COUNT(score) 返回 7,COUNT(*) 是 10。如果你本意是“全体用户平均分”,那结果就少了近 30% 的基数支撑。
更危险的是:这个过程完全静默。没有警告,不报错,只默默改分母。
COALESCE(score, 0) 看似补全,实则语义污染
把 NULL 强制转成 0,不是“填默认值”,而是把“未知”篡改为“已知为零”。尤其在业务含义敏感的场景下,偏差会非常剧烈:
- 传感器表中
temperature IS NULL表示“设备离线”,填 0 后均值被系统性拉低 - 员工表中
salary IS NULL可能代表“未定薪”或“合同工无底薪”,填 0 就等于认定他们“零收入” -
AVG(COALESCE(score, 0))的分母仍是COUNT(score),不是COUNT(*),所以它 ≠SUM(COALESCE(score, 0)) / COUNT(*)
空结果集返回NULL,应用层直接崩
当过滤后没数据,比如 SELECT AVG(score) FROM ratings WHERE user_id = 999,结果就是 NULL。这在代码里极易引发异常:
- Java 中
ResultSet.getDouble()直接抛SQLException - Python 中
row[0]是None,后续参与算术运算触发TypeError - 前端渲染时显示为
null字符串或空白,而非“暂无数据”
必须显式兜底:IFNULL(AVG(score), 0)(MySQL)或 COALESCE(AVG(score), 0)(通用)。
GROUP BY + AVG() 时,分母边界最容易被忽略
你在子查询或视图里嵌套了 AVG(x),外部再加 WHERE,分母已经不是原始表的 COUNT(*),也不是你直觉里的“这组该有多少人”。唯一靠谱的办法,是在最终 SELECT 里并列输出:
AVG(score)-
COUNT(score)(实际参与计算的行数) -
COUNT(*)(该组总行数)
三者对照着看,才能判断这个平均值是否符合业务口径——比如 COUNT(score) / COUNT(*) 低于 60%,说明大量数据缺失,AVG() 结果参考价值极低。

















