ROUND()函数在SQL中专用于四舍五入:decimals为正数时保留小数位(如ROUND(1.298,1)→1.3),为0时取整(ROUND(12.5,0)→13),为负数时向左舍入(ROUND(123.45,-1)→120);支持NULL输入返回NULL,但浮点精度可能导致意外结果。

ROUND() 函数在 SQL 查询中默认就是四舍五入,不是截断、也不是向上取整。只要传入正确的参数,它就能按需控制小数位或整数位精度。
ROUND(column_name, decimals) 中 decimals 为正数时怎么用
这是最常见场景:保留小数点后几位。比如价格字段 price 经常要保留 2 位小数用于展示。
- 写法是
SELECT ROUND(price, 2) FROM orders,结果如19.99、25.00 - 注意:如果原始值是
NULL,ROUND()也返回NULL,不会报错但可能影响后续计算 - MySQL 中
ROUND(1.298, 1)返回1.3(类型变为DECIMAL或FLOAT,不是BIGINT;只有ROUND(x)不带第二参数时才可能转成整型) - PostgreSQL 和 SQL Server 行为一致,但 Oracle 对负零处理略有差异,不过日常使用基本无感
ROUND(number, -1) 这类负数参数实际效果是什么
负数的 decimals 表示对小数点左边进行四舍五入,常用于数据聚合或简化显示,比如把销售额按“十元”“百元”归类。
-
ROUND(123.456, -1)→120.0(个位四舍五入到十位) -
ROUND(167.89, -1)→170.0(67.89 ≥ 65,所以进到 170) -
ROUND(626.3, -3)→1000.0(626.3 四舍五入到千位,因为 626.3 ≥ 500) - 容易踩的坑:
ROUND(1.98, -1)得到0,不是报错——它是在“十位”上四舍五入,1.98 小于 5,所以归到 0
ROUND() 在不同数据库里有哪些关键行为差异
核心逻辑一致,但细节决定是否出 bug。尤其跨数据库迁移或写兼容 SQL 时得留心。
- MySQL:对
ROUND(-1.5)返回-2,符合数学四舍五入规则;但旧版本(5.0 之前)有“银行家舍入”争议,现版本已统一 - SQL Server:
ROUND(123.456, -2)返回100.0,和 MySQL 一样;但若字段是MONEY类型,内部精度可能影响结果 - PostgreSQL:严格遵循 IEEE 标准,
ROUND(2.5)→3,ROUND(-2.5)→-3,没有“向偶数舍入”逻辑 - Oracle:
ROUND(123.456, -2)同样是100,但它允许ROUND(date_column, 'MM')这种日期用法,和数值ROUND()是两个函数重载
为什么 ROUND(1.235, 2) 有时不等于 1.24
这不是函数 bug,而是浮点数存储导致的精度丢失。真实值可能根本不是精确的 1.235,而是 1.2349999999999999。
- 典型表现:
SELECT ROUND(1.235, 2)在某些环境返回1.23,尤其当该值来自计算列(如sum(a)/count(b))时 - 解决办法:先用
CAST(... AS DECIMAL(10,3))强制转为定点数再ROUND,例如ROUND(CAST(1.235 AS DECIMAL(10,3)), 2) - 另一个思路是加极小扰动:
ROUND(x + 0.0000001, 2),但仅限业务能容忍微小偏移的场景 - 真正需要确定性舍入的场合(如财务),建议在应用层做
BigDecimal或decimal运算,别全压给数据库










