FLOOR向下取整(朝负无穷),CEILING向上取整(朝正无穷);例如FLOOR(-2.1)=-3,CEILING(-2.1)=-2;二者不四舍五入、不支持精度参数,需配合乘除实现保留N位小数取整。

SQL中FLOOR和CEILING的基本行为差异
FLOOR永远向下取整(朝负无穷方向),CEILING永远向上取整(朝正无穷方向)。这不是四舍五入,也不受小数位数影响——哪怕输入是 -2.1,FLOOR(-2.1) 得到 -3,CEILING(-2.1) 得到 -2。
常见误用是当成“舍去小数”或“进一位”,但负数时结果完全相反。比如计算折扣后最低应付金额,若用错函数,可能让客户少付钱。
-
FLOOR(4.9)→4;FLOOR(-4.9)→-5 -
CEILING(4.1)→5;CEILING(-4.1)→-4 - 两函数都只接受一个数值表达式,不支持指定精度(如“保留1位小数后取整”需先乘除再调用)
如何配合乘除实现“保留N位小数后取整”
数据库原生FLOOR/CEILING不带精度参数,要实现“保留2位小数后向下取整”,得手动缩放:先放大100倍,取整,再缩小回去。
例如将 price 字段保留2位小数后向下取整:
FLOOR(price * 100) / 100.0
注意除数写成 100.0 而非 100,避免整数除法截断(尤其在 PostgreSQL 或 SQL Server 中)。
- 保留1位:用
* 10和/ 10.0 - 保留3位:用
* 1000和/ 1000.0 - MySQL 8.0+、PostgreSQL 支持
ROUND(x, n),但ROUND是四舍五入,不是向上/向下
不同数据库对CEILING的函数名兼容性问题
SQL 标准用 CEILING,但 MySQL 早期版本只认 CEIL(无 E),且至今仍更常用 CEIL。PostgreSQL、SQL Server、Oracle 都同时支持两者,但 SQLite 只支持 CEIL。
写跨库 SQL 时,优先用 CEIL 更稳妥;如果明确只跑 SQL Server,用 CEILING 也没问题。
- MySQL 5.7+:推荐
CEIL(x),CEILING(x)也行 - PostgreSQL:两个都行,但文档示例多用
CEIL - SQLite:只认
CEIL(x),用CEILING直接报错no such function: CEILING
浮点精度导致的意外结果
当输入来自计算表达式(如 10.0 / 3),浮点误差可能让本该是 3.3333333333333335 的值被 FLOOR 判定为略大于 3.333…,但实际显示截断后看起来一样。这种误差在金融场景里容易引发对账偏差。
解决办法不是硬加容差,而是从源头控制精度:用 DECIMAL 类型存储金额,或在计算前显式转成定点数。
- 坏例子:
FLOOR(10.0 / 3 * 100)→ 理论上应得333,但可能因浮点误差得334 - 好做法:
FLOOR(CAST(10 AS DECIMAL(10,2)) / CAST(3 AS DECIMAL(10,2)) * 100) - 更简单:如果只是金额处理,直接用
ROUND(x, 2)配合业务规则判断是否进位
真正需要FLOOR/CEIL的,往往是分页页码计算、资源配额分配这类离散整数逻辑,而不是小数精度控制——后者更适合用定点数类型 + ROUND 组合。

















