ROUND函数并非万能开关,其结果取决于使用环境与参数:decimals为正数时保留小数位,为0时取整,为负数时向小数点左侧舍入,如ROUND(1.98,-1)得0。

ROUND 函数能直接四舍五入,但结果是否符合预期,取决于你用在哪、怎么传参、用在什么数据库里——它不是“写上就准”的万能开关。
ROUND(number, decimals) 的参数到底怎么填
decimals 是关键控制位,不是“保留几位有效数字”,而是“小数点后/前第几位开始舍入”:
• 正数(如 2):保留小数点后两位,ROUND(12.345, 2) → 12.35
• 零(0):四舍五入到整数,ROUND(9.7, 0) → 10
• 负数(如 -1):对个位舍入,ROUND(127, -1) → 130;ROUND(1.98, -1) → 0(不是报错,是按十位舍入,1.98 • 必须传两个参数:MySQL 和 PostgreSQL 允许省略第二参数(等价于 0),但 SQL Server 和 Oracle 会报错或截断,跨库迁移时务必显式写出
为什么 ROUND(1.235, 2) 有时返回 1.23 而不是 1.24
这不是函数出错,是浮点数底层二进制表示导致的精度丢失。真实值可能存为1.2349999999999999,ROUND 拿到的已不是精确的 1.235。
• 常见于计算列,比如 ROUND(SUM(a)/COUNT(b), 2)
• 解决办法:先转定点数再舍入,例如 ROUND(CAST(value AS DECIMAL(10,3)), 2)
• MySQL 5.7+ 和 PostgreSQL 对此更稳定,但 FLOAT 类型始终有风险;财务场景必须用 DECIMAL 存原始值
SQL Server 的 ROUND 默认不是“四舍五入”,而是“四舍六入五成双”
SQL Server 的ROUND 遵循 IEEE 754 银行家舍入规则:遇到 .5 结尾时向偶数靠拢。这对统计合理,但财务报表常要求严格进位。
• ROUND(1.5, 0) → 2,但 ROUND(2.5, 0) → 2(不是 3)
• 真正要“0.5 就进一”,得绕开 ROUND:FLOOR(value * 100 + 0.5) / 100.0
• 别用 ROUND(value + 0.005, 2):浮点误差会让 1.235 + 0.005 ≠ 1.240,尤其在 MONEY 或边界值上不可靠
ROUND 结果带尾随零(如 13.150)怎么去掉
ROUND 是数学函数,不负责格式化输出。它返回的类型继承自输入字段——如果原字段是 DECIMAL(10,3),结果还是三位小数。
• 想显示为 13.15,必须显式转换:CAST(ROUND(price, 2) AS DECIMAL(10,2))
• MySQL 可用 CONVERT(DECIMAL(10,2), ROUND(price, 2))
• 这步不能省:前端或报表工具看到 13.150 可能自动补零或解析失败
最易被忽略的一点:你在 WHERE 或 GROUP BY 里用 ROUND(amount, 0) = 100,数据库大概率没法走 amount 字段上的索引——因为函数改变了原始值。真要高频过滤,得建函数索引,或者改用范围条件:amount >= 99.5 AND amount 。

















