round函数行为因数据库而异:mysql/postgresql支持正负小数位,sql server第二参数须非负;round返回数值类型,不控制显示格式;确保两位小数需配合cast或类型转换,而非仅用round。

ROUND函数的基本用法和参数含义
ROUND 在 SQL 中不是万能四舍五入工具,它的行为取决于数据库类型。MySQL 和 PostgreSQL 支持两位参数:ROUND(number, decimals),其中 decimals 可正可负;SQL Server 的 ROUND 第二个参数是 length,但**必须是非负整数**,负数会报错;Oracle 则允许负数,表示向左取整(如 -1 表示精确到十位)。
常见错误是直接写 ROUND(price, 2) 就以为一定返回两位小数 —— 实际返回的是数值类型,显示位数由客户端或上层应用控制,不是字符串格式化。
- 想让结果固定显示两位小数,得配合
CAST或TO_CHAR(PostgreSQL/Oracle)或FORMAT(MySQL 8.0+) - SQL Server 中
ROUND(123.456, 2)返回123.460(注意末尾的 0),类型仍是decimal,精度未丢 - 如果原始字段是
float,先ROUND再转decimal才能避免浮点误差累积
不同数据库中保留两位小数的可靠写法
目标:查询 amount 字段并确保结果为「数值型 + 精确到小数点后两位」,不依赖前端处理。
MySQL:
SELECT ROUND(amount, 2) AS amount FROM orders;
但如果要强制补零(如 123.4 → 123.40),得用:
SELECT FORMAT(amount, 2) AS amount FROM orders;
注意:FORMAT 返回字符串,不能参与后续数值计算。
PostgreSQL:
SELECT ROUND(amount, 2)::DECIMAL(10,2) AS amount FROM orders;
显式转成 DECIMAL(10,2) 既能截断位数,又保留数值类型。
SQL Server:
SELECT CAST(ROUND(amount, 2) AS DECIMAL(10,2)) AS amount FROM orders;
不能只用 ROUND(amount, 2),因为默认可能返回 money 或高精度 decimal,末尾零不保证。
ROUND遇到NULL或非数字时的行为
ROUND(NULL, 2) 在所有主流数据库中都返回 NULL,不会报错 —— 这是安全的,但容易掩盖数据质量问题。
- 如果
amount来自多表 JOIN,且某行值为NULL,ROUND后仍是NULL,别误以为是 0 - 字符串型数字(如
'123.45')在 PostgreSQL 和 SQL Server 中会隐式转换,MySQL 5.7 严格模式下会报错,需提前CAST(col AS DECIMAL) - 对负数使用
ROUND(-1.25, 1):MySQL 和 PostgreSQL 返回-1.2(银行家舍入?不,这是标准四舍五入),SQL Server 也是-1.2;但要注意某些旧版 MySQL 有 bug,建议升级
为什么有时候ROUND没生效?检查这三点
最常被忽略的是字段原始类型和精度定义。
- 源字段是
DECIMAL(10,4),但业务只要两位,ROUND(x, 2)后仍为DECIMAL(10,4)类型(SQL Server),显示时可能带多余零 - SELECT 中用了表达式如
price * 0.9,再ROUND,但中间计算可能溢出或降精度,应先CAST再运算 - 应用连接数据库时设置了
SET ARITHABORT OFF(SQL Server)或自动类型推导,导致ROUND结果被客户端按原始列定义渲染
真正保险的做法:始终显式 CAST 或 ::type 指定输出精度,而不是只依赖 ROUND。










