round函数语法为round(number, decimals),支持正、零、负小数位数,但各数据库对四舍五入规则、类型返回及默认参数处理存在差异,使用时需注意精度、类型兼容性及业务语义匹配。

ROUND函数的基本用法和参数含义
ROUND 在大多数主流数据库(如 MySQL、PostgreSQL、SQL Server)中都支持,但行为有细微差别。核心用法是 ROUND(number, decimals):第一个参数是待处理的数值表达式,第二个是保留的小数位数(可为负数)。注意:MySQL 和 SQL Server 默认四舍五入,而 PostgreSQL 的 ROUND 也遵循 IEEE 标准,但对 .5 的处理一致(向偶数舍入的情况极少在业务中暴露,一般可认为是四舍五入)。
- 小数位数为正数(如
2):保留到小数点后两位,ROUND(123.456, 2)→123.46 - 小数位数为 0:四舍五入到整数,
ROUND(123.5, 0)→124 - 小数位数为负数(如
-1):向左舍入,ROUND(123.456, -1)→120(即十位取整) - 省略第二个参数时,MySQL 和 SQL Server 默认为 0;PostgreSQL 则报错,必须显式传参
不同数据库对 ROUND 的兼容性陷阱
看似统一的函数,在实际跨库迁移或联合开发时容易出错。最典型的是 SQLite —— 它的 ROUND 返回的是 REAL 类型,即使你 ROUND(x, 0),结果仍是浮点数(如 123.0),而非整数类型;而 PostgreSQL 的 ROUND 对 NUMERIC 输入返回 NUMERIC,对 DOUBLE PRECISION 返回 DOUBLE PRECISION,类型不一致可能影响后续 CASE 或聚合判断。
- MySQL 中
ROUND(15.5)和ROUND(14.5)都返回整数(16和14),符合直觉 - PostgreSQL 中
ROUND(2.5)→2,ROUND(3.5)→4(银行家舍入),但日常金额计算中几乎感知不到差异 - SQL Server 的
ROUND严格四舍五入,但若字段是FLOAT类型,先存在二进制精度误差,再ROUND可能出现意外结果,例如ROUND(0.1 + 0.2, 1)在某些版本返回0.3,某些返回0.29999999999999999
在 SELECT 查询中安全使用 ROUND 的实操建议
直接在 SELECT 中用 ROUND 没问题,但要注意它不改变原始数据,只是临时格式化输出。真正要小心的是参与后续计算或比较时的隐式类型转换。
- 避免对
FLOAT或REAL字段直接ROUND后用于WHERE条件,比如WHERE ROUND(price, 2) = 19.99—— 浮点误差可能导致匹配失败;应改用范围判断:WHERE price BETWEEN 19.985 AND 19.995 - 金额类字段优先定义为
DECIMAL(p,s),再用ROUND,能消除大部分精度干扰 - 如果需要固定两位小数且补零(如
123.1→123.10),ROUND不负责补零,需配合FORMAT(MySQL/SQL Server)或TO_CHAR(PostgreSQL),但那是显示层逻辑,不应混入计算逻辑 - 在 GROUP BY 或 ORDER BY 中使用
ROUND要确认是否真有必要——多数时候应先聚合再四舍五入,而不是先四舍五入再聚合,否则会放大误差
ROUND 无法替代的场景:你需要的是截断或向上/向下取整
四舍五入不是万能的。比如计算折扣后价格展示时要求“不高于原价”,就得用 FLOOR;做分页计数时统计“至少需要几页”,就得用 CEILING;而 ROUND 有时反而破坏业务语义。
-
FLOOR(123.999)→123,CEILING(123.001)→124,二者都不受小数部分大小影响 -
TRUNCATE(MySQL)或TRUNC(PostgreSQL)可直接截掉小数位,不四舍五入,TRUNCATE(123.999, 2)→123.99 - SQL Server 没有原生
TRUNC,可用ROUND(x, s, 1)实现截断(第三个参数为1表示截断而非舍入) - 别试图用
ROUND(x * 100) / 100替代ROUND(x, 2)—— 这样写多此一举,且在极端值下可能引入额外浮点误差
ROUND 的边界情况不多,但一旦出错往往难定位。关键是分清:这是展示需求,还是计算中间步骤?前者可放宽容忍度,后者必须明确数据类型和误差来源。











