AVG() 默认返回基于字段类型和内部计算精度的浮点结果,不控制小数位数;ROUND(AVG(x), 2) 最稳妥,因它明确四舍五入、不受源类型干扰,且须紧贴AVG()使用。

AVG() 默认返回什么精度?
MySQL 的 AVG() 函数本身不控制小数位数,它返回的是基于字段类型和内部计算精度的浮点结果。比如 score 是 INT 类型,AVG(score) 可能返回 87.7500;如果是 DECIMAL(5,2),结果可能只保留两位但末尾补零。这容易让人误以为“已经四舍五入”,其实只是显示习惯或字段隐式影响——真实值可能有更多有效位。
为什么直接写 ROUND(AVG(x), 2) 是最稳妥的做法?
因为 ROUND() 明确执行四舍五入并截断到指定小数位,不受源字段类型干扰。它在聚合完成后再处理数值,逻辑清晰、行为可预期。
-
ROUND(AVG(score), 2):先算平均,再四舍五入到两位小数 - 别用
CAST(AVG(score) AS DECIMAL(10,2)):虽然也能截断,但 CAST 不四舍五入,而是直接截断(如87.759→87.75) - 别依赖客户端格式化:PHP/Python 等语言做 round() 容易因浮点误差出错,应在 SQL 层就定死精度
GROUP BY 场景下怎么加 ROUND?
ROUND 必须包裹在聚合表达式内部,不能放在外面,否则会报错 Invalid use of group function。
正确写法:SELECT department, ROUND(AVG(salary), 2) AS avg_salary FROM employees GROUP BY department;
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
错误写法:SELECT department, ROUND(AVG(salary), 2) FROM employees GROUP BY department;(缺别名不影响语法,但没别名难读;真正错的是把 ROUND 放错位置)
- ROUND 必须紧贴
AVG(),作为其直接外层函数 - 如果还要做空值兜底,顺序是
ROUND(COALESCE(AVG(x), 0), 2),不是COALESCE(ROUND(AVG(x), 2), 0) - WHERE 条件写在 GROUP BY 前,HAVING 写在 GROUP BY 后——ROUND 不影响这个顺序
容易被忽略的 NULL 处理细节
AVG() 自动跳过 NULL 值,这点没问题;但如果你的字段允许 NULL,而业务上希望把 NULL 当作 0 参与计算,就不能只靠 AVG()。
- 想忽略
NULL:直接AVG(score)(默认行为) - 想把
NULL当 0:用AVG(IFNULL(score, 0))或AVG(COALESCE(score, 0)) - 想排除
NULL且排除 0 值(比如 0 表示未打分):加 WHEREscore > 0,而不是在 AVG 里做判断
ROUND 和 NULL 无关,但它会如实作用于 AVG 的输出结果——所以前一步怎么定义“平均”,决定了 ROUND 处理的是什么数。

















