ROUND函数不是万能开关,其结果取决于参数、数据库和输入类型:decimals为正数时保留小数位,为0时取整,为负数时向左舍入(如ROUND(1.98,-1)得0);跨库需显式传参;浮点数精度失真会导致ROUND(1.235,2)返回1.23;应先CAST为DECIMAL再ROUND。

ROUND 函数不是“写上就准”的格式化工具,它只做数值舍入,结果是否符合预期,取决于你传什么、在哪用、用哪个数据库。
ROUND(number, decimals) 的 decimals 参数怎么填才不翻车
decimals 控制的是“从哪一位开始舍入”,不是“保留几位有效数字”:
• 正数(如 2):小数点后第 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 小于 5,归零)
• 必须显式传两个参数:MySQL/PostgreSQL 允许省略第二参数(默认为 0),但 SQL Server 和 Oracle 会报错或静默截断,跨库迁移务必写全
为什么 ROUND(1.235, 2) 有时返回 1.23 而不是 1.24
这不是函数 bug,而是输入值本身精度已失真:• 浮点类型(FLOAT、REAL)无法精确存储十进制小数,1.235 在内存中可能是 1.2349999999999999
• MySQL 的 ROUND 对浮点数遵循 IEEE 标准,“四舍六入五成双”,ROUND(2.5, 0) 返回 2(偶数优先)
• PostgreSQL v13+ 默认银行家舍入,SQL Server 才是传统四舍五入
• 解决办法:先 CAST(price AS DECIMAL(10,4)),再 ROUND(..., 2);金额类字段建表时就该用 DECIMAL,别指望 ROUND 补救
ROUND 后结果带尾随零(如 13.150)怎么办
ROUND 不改变数据类型,结果类型继承源字段:
• 如果原始列是 FLOAT 或 NUMERIC(10,4),ROUND(col, 2) 仍可能返回 13.150(三位小数)
• 想要干净的两位小数显示,得靠类型转换:CAST(ROUND(col, 2) AS DECIMAL(10,2)) 或直接 CAST(col AS DECIMAL(10,2))(后者更稳,因 CAST 本身含四舍五入)
• CONVERT(DECIMAL(10,2), col) 在 SQL Server 中效果等同于 CAST,且更明确控制精度
在 GROUP BY 或 WHERE 里用 ROUND 要格外小心
看似相等的舍入结果,底层可能分属不同组:• ROUND(1.234999, 2) 和 ROUND(1.235001, 2) 都是 1.24,但如果原始值是 FLOAT,中间计算已漂移
• 分组时建议先统一精度:ROUND(CAST(amount AS DECIMAL(12,4)), 2)
• 条件判断慎用 WHERE ROUND(x, 2) = 1.24,改用范围:WHERE x BETWEEN 1.235 AND 1.245
• 最容易被忽略的,从来不是 ROUND 怎么写,而是它接收到的值——是不是从一开始就该是 DECIMAL

















