FLOOR向负无穷取整(如FLOOR(-2.1)=-3),CEILING向正无穷取整(如CEILING(-2.1)=-2);二者行为跨库一致,不支持精度参数,不可用ROUND替代。

SQL中FLOOR和CEILING函数的基本行为
FLOOR 总是向下取整到最接近的整数(不考虑正负号方向,而是朝负无穷方向),CEILING 总是向上取整到最接近的整数(朝正无穷方向)。这不是四舍五入,也不受小数部分大小影响——哪怕只有0.0001,FLOOR(3.0001) 仍是 3,CEILING(-2.9999) 是 -2。
常见错误现象:FLOOR(-2.3) 返回 -3(不是 -2),有人误以为“向下”是数值变小,其实它是向数轴左侧移动;同理 CEILING(-2.3) 返回 -2,不是 -3。
- MySQL、PostgreSQL、SQL Server、Oracle 都支持这两个函数,行为一致
- SQLite 不原生支持
CEILING,需用-FLOOR(-x)模拟 - 输入为
NULL时,两者均返回NULL
处理小数位数:FLOOR/CEILING 不能直接指定精度
FLOOR 和 CEILING 只接受单个数值参数,不支持类似 ROUND(x, 2) 的小数位参数。想保留两位小数再取整?得手动缩放:
例如:把 123.456 向下取整到百分位(即 123.45),要写成 FLOOR(123.456 * 100) / 100.0;向上则用 CEILING(123.456 * 100) / 100.0。
- 乘除必须匹配:
FLOOR(x * 10^N) / 10.0^N,注意分母用浮点数(如100.0)避免整数除法截断 - PostgreSQL 中可结合
NUMERIC类型避免浮点误差,MySQL 则建议用DECIMAL字段存原始值 - 在 WHERE 或 ORDER BY 中频繁缩放可能影响索引使用,慎用于大表过滤条件
与 ROUND、TRUNCATE 的关键区别
ROUND 是四舍五入,TRUNCATE(或 TRUNC)是直接截断小数部分(朝零方向),而 FLOOR/CEILING 是朝无穷方向。三者对负数结果差异明显:
FLOOR(-1.7) → -2 CEILING(-1.7) → -1 ROUND(-1.7) → -2 (默认四舍五入) TRUNCATE(-1.7)→ -1 (MySQL)或 TRUNC(-1.7) → -1(PostgreSQL)
- 业务场景决定选哪个:计算折扣后最低应付金额用
FLOOR,分配最小整箱数用CEILING,显示报表摘要数字用ROUND - SQL Server 的
ROUND支持负精度(如ROUND(123.456, -1)→120),但FLOOR/CEILING没有该能力 - 某些旧版 MySQL(FLOOR 在浮点列上存在精度异常,建议先
CAST(x AS DECIMAL(10,4))再调用
实际应用中的坑:隐式类型转换和 NULL 处理
当字段是字符串或混合类型时,数据库可能静默转成浮点再计算,导致意外结果。比如 FLOOR('123.9') 在 MySQL 中能运行,但 FLOOR('abc') 变成 0(而非报错);PostgreSQL 则直接报错。
- 始终确保输入是数值类型,必要时加
CAST(col AS NUMERIC)或TRY_CAST(SQL Server 2012+) - WHERE 子句中用
FLOOR(price) = 10会丢失索引,改用price >= 10 AND price 更高效 - 聚合中嵌套
FLOOR(如AVG(FLOOR(x)))会先取整再平均,和先平均再取整语义不同,务必确认业务逻辑
真正麻烦的不是函数本身,而是它在边界值、负数、隐式转换和性能约束下的组合表现——多数问题出在没意识到 FLOOR 对负数的“向下”是往更小的数走,而不是去掉小数部分。

















