ROUND函数将数字四舍五入到指定位数:正数精度舍入小数位,0舍入到整数,负数精度舍入小数点左侧;必须传两个参数,不同数据库对负精度和浮点误差处理存在差异。

ROUND函数四舍五入的正确用法
ROUND 是标准 SQL 中最常用的四舍五入函数,但它的行为在不同数据库中略有差异。MySQL 和 PostgreSQL 默认对小数点后一位四舍五入;SQL Server 和 Oracle 则要求显式指定精度参数,否则可能报错或截断为整数。
关键点:必须传入两个参数——数值和精度位数,否则结果不可控。比如 ROUND(3.14159, 2) 返回 3.14,而 ROUND(3.14159, 0) 返回 3。
- 精度为负数时(如
ROUND(1234.56, -2))会向左舍入到百位,结果是1200 - 某些数据库(如 SQLite)不支持负精度,会直接报错
no such function: ROUND - 浮点数参与计算时,可能因二进制表示误差导致“看似该进位却没进”,例如
ROUND(2.675, 2)在部分环境下返回2.67而非2.68
TRUNCATE不是四舍五入,别误用
TRUNCATE 在 MySQL 中存在,但它**不四舍五入**,只是截断小数位。比如 TRUNCATE(3.999, 2) 得到 3.99,TRUNCATE(-3.999, 2) 得到 -3.99——它朝零方向截断,永远不进位。
PostgreSQL 没有 TRUNCATE 数值函数(只有表级命令 TRUNCATE TABLE),若误写会报错 function truncate(numeric, integer) does not exist。
- 想实现“向下取整到指定位数”,可用
FLOOR(x * POWER(10,n)) / POWER(10,n)替代 - Oracle 里对应的是
TRUNC(少一个 E),拼错就调用不到函数 - SQL Server 不支持
TRUNCATE数值操作,只能用ROUND(x, n, 1)(第三个参数为 1 表示截断)
不同数据库的兼容写法建议
如果 SQL 需跨库运行(比如应用同时对接 MySQL 和 PostgreSQL),避免依赖 TRUNCATE,统一用 ROUND + 显式精度,并注意负精度支持情况。
对严格截断需求,可封装逻辑:先乘幂、再用 FLOOR 或 CEILING、最后除幂。例如保留两位小数并向下截断:FLOOR(x * 100) / 100.0。
- MySQL 支持
ROUND(x, n)和TRUNCATE(x, n),但后者语义不同 - PostgreSQL 必须用
ROUND(x, n),或TRUNC(x, n)(函数名是TRUNC,不是TRUNCATE) - SQL Server 的
ROUND(x, n, 1)第三个参数为 1 时等价于截断 - SQLite 只支持
ROUND(x)和ROUND(x, n),不支持负精度
容易被忽略的隐式类型转换陷阱
当字段是 DECIMAL 或 NUMERIC 类型时,ROUND 的结果仍保持原精度定义;但如果参与运算的列是 FLOAT,四舍五入结果可能意外失真。
例如在 MySQL 中:SELECT ROUND(0.295, 2) 有时返回 0.29,因为底层存储是近似值。这不是函数 bug,而是浮点表示局限。
- 涉及金额、科学计数等高精度场景,优先用
DECIMAL类型存储原始值 - 避免在
WHERE子句中对ROUND结果做等值比较,比如ROUND(price, 2) = 19.99可能漏数据 - 如需稳定舍入,考虑在应用层处理,或使用数据库特定扩展(如 PostgreSQL 的
round_bankers扩展)
实际业务中,多数人真正需要的不是“四舍五入”,而是“显示友好+计算准确”的平衡——这时候往往得放弃纯 SQL 处理,把舍入逻辑交给应用代码控制。










