答案是使用round函数实现数值四舍五入,其语法为round(numeric_expression, decimal_places),正数保留小数位、0取整、负数向左舍入,但行为因数据库而异:mysql和postgresql默认标准四舍五入,sql server结果保持原精度类型需cast显式截断。

ROUND 函数能按需四舍五入,但行为受数据库类型和参数顺序影响,直接套用可能出错。
MySQL 和 PostgreSQL 中 ROUND 的基本用法
这两个系统都支持 ROUND(number, decimals) 形式,第二个参数决定保留几位小数。正数表示小数位,0 表示取整,负数则向左舍入(如 ROUND(1234.56, -2) 得 1200)。
- MySQL 默认使用“银行家舍入”(偶数优先)吗?不,MySQL
ROUND()是标准四舍五入(5 及以上进位) - PostgreSQL 同样是标准四舍五入,但注意:如果
decimals为NULL,整个结果变成NULL,不是报错 - 示例:
SELECT ROUND(3.14159, 2);→3.14;ROUND(2.5, 0)→3
SQL Server 的 ROUND 不返回截断值,而是保持原精度类型
SQL Server 的 ROUND(numeric_expression, length) 第二个参数叫 length,语义一致,但关键区别在于:它不会自动把结果转成更短的小数类型。比如对 DECIMAL(10,4) 字段执行 ROUND(col, 2),结果仍是 DECIMAL(10,4),末尾带两个零(如 3.1400),而非 3.14。
- 若要真正“显示”为两位小数,得配合
CAST或CONVERT,例如:CAST(ROUND(price, 2) AS DECIMAL(10,2)) - 当
length为负数时,SQL Server 支持(如ROUND(1234.56, -1)→1230.00),但长度不能超过原始精度,否则报错Arithmetic overflow error
ROUND 在 GROUP BY 或 ORDER BY 中的隐式类型陷阱
在聚合或排序中直接写 ROUND(amount, 2) 看似没问题,但某些数据库(尤其是旧版 SQLite 或未显式声明类型的场景)会把结果当作浮点数处理,导致 GROUP BY ROUND(x,2) 把本该相等的 1.230 和 1.23 视为不同键。
- 安全做法是统一用
CAST固定输出类型,例如:CAST(ROUND(total, 2) AS DECIMAL(12,2)) - 避免在
WHERE条件里对列用ROUND(col, 2) = 1.23——这会阻止索引使用;应改写为范围查询:col >= 1.225 AND col - SQLite 的
ROUND()返回的是浮点数,且不支持负数digits参数,传-1会静默忽略
ROUND 行为差异最常出现在跨数据库迁移或对接 BI 工具时——表面结果一样,底层类型或空值处理稍有不同,就可能让前端展示多出一串零,或聚合计数变少。动手前先查清你用的是哪个数据库的文档,别只看函数名。











