ROUND函数将数字四舍五入到指定位数,语法为ROUND(number, num_digits),其中number为待处理数值,num_digits为舍入位数:大于0时保留小数位,等于0时取整,小于0时向小数点左舍入。

ROUND函数的基本用法和参数含义
ROUND 是 SQL 中最常用的数值四舍五入函数,但不同数据库对它的行为有细微差别。核心参数是两个:number(要处理的数值)和 decimal_places(保留小数位数)。第二个参数可正可负:正数表示小数点后几位,负数表示向整数高位舍入(比如 -1 表示舍入到十位)。
常见错误是传入非数字类型或 NULL —— 大多数数据库会直接返回 NULL,而不是报错,容易被忽略。
- PostgreSQL 和 SQL Server 支持负数位数,MySQL 8.0+ 也支持,但 MySQL 5.7 对负数位数处理不一致
- 如果
decimal_places是变量或表达式,需确保它为整数,否则某些数据库(如 Oracle)会报ORA-01722: invalid number - 浮点数参与计算时可能引入精度误差,例如
ROUND(1.235, 2)在部分系统中可能得1.23而非1.24(因底层存储不是精确十进制)
不同数据库中ROUND的行为差异
看似统一的 ROUND,实际在“四舍六入五成双”还是“传统四舍五入”上并不统一。SQL Server 默认用“四舍五入”,而 PostgreSQL 的 ROUND 是“四舍六入五成双”(银行家舍入),这会影响统计类查询结果的准确性。
例如对列 price 执行 ROUND(price, 2):
- SQL Server / MySQL:1.235 →
1.24,1.245 →1.25 - PostgreSQL:1.235 →
1.24,但 1.245 →1.24(因 4 是偶数) - 若需强制传统四舍五入,PostgreSQL 可改用
ROUND(price + 0.005, 2),但要注意边界溢出风险
在SELECT和WHERE中使用ROUND的注意事项
ROUND 常用于 SELECT 展示格式化数值,但误用在 WHERE 条件里可能导致索引失效或逻辑偏差。例如写 WHERE ROUND(amount, 0) = 100,数据库无法利用 amount 字段上的普通 B-tree 索引,因为函数改变了原始值。
- 更安全的写法是改用范围判断:
WHERE amount >= 99.5 AND amount - 如果必须用函数过滤,且查询频繁,可考虑创建函数索引(如 PostgreSQL 的
CREATE INDEX idx_rounded ON tbl ((ROUND(amount, 0)))) - 在
GROUP BY中用ROUND(price, 1)分组时,注意相同显示值可能来自不同原始区间(如 1.249 和 1.251 都变成 1.2),这不是 bug,而是舍入的必然结果
替代方案:CEILING、FLOOR 和 CAST/CONVERT 的适用场景
当不需要标准四舍五入时,ROUND 反而会误导。比如做价格向上取整(收银场景),该用 CEILING;做截断取整(避免进位),该用 FLOOR 或 TRUNCATE(MySQL)。
-
CEILING(1.1)→2,FLOOR(1.9)→1,两者都不受小数位影响 - MySQL 的
TRUNCATE(1.999, 1)直接截掉多余位,得1.9;而ROUND(1.999, 1)得2.0 - 用
CAST(x AS DECIMAL(10,2))在某些数据库中只是类型转换,不触发舍入(如 SQL Server),需配合ROUND显式调用
真正麻烦的不是函数怎么写,而是没想清楚业务到底要“展示近似值”还是“按舍入规则重新计量”。前者用 ROUND 没问题,后者得确认数据库是否真按你的预期执行了舍入逻辑。

















