FLOOR向下取整、CEILING向上取整,均返回整数且对NULL返回NULL;注意负数行为(如FLOOR(-2.7)=-3)、数据库别名差异(SQL Server仅支持CEILING)、索引失效问题及浮点精度风险。

SQL中FLOOR和CEILING函数的基本行为
FLOOR 向下取整,返回不大于参数的最大整数;CEILING(或 CEIL,取决于数据库)向上取整,返回不小于参数的最小整数。它们都只接受数值类型参数,对 NULL 返回 NULL。
注意:PostgreSQL 和 MySQL 支持 CEIL 别名,但 SQL Server 只认 CEILING;Oracle 两者都支持。别写成 CEILING() 在 MySQL 里会报错 FUNCTION xxx.CEILING does not exist。
常见错误:对负数取整结果不符合直觉
比如 FLOOR(-2.7) 返回 -3,不是 -2;CEILING(-2.7) 返回 -2,不是 -3。这是因为「向下」和「向上」是按数轴方向理解的,不是按绝对值。
- 误以为
FLOOR(-1.2)是-1→ 实际是-2 - 在计算分页偏移量时用
FLOOR((page-1)*size)处理负页码,会得到意外负值 - 做金额四舍五入前先截断小数位,应优先考虑
TRUNCATE或ROUND,而非FLOOR直接套用
与ROUND配合实现“向零取整”或“截断小数”
标准 FLOOR/CEILING 无法直接实现朝零取整(如 -2.7 → -2, 2.7 → 2),需结合符号判断:
SELECT x, CASE WHEN x >= 0 THEN FLOOR(x) ELSE CEILING(x) END AS trunc_to_zero FROM (VALUES (-2.7), (2.7), (-0.3), (0.3)) t(x);
这个模式在清理用户输入的浮点型ID、版本号或索引偏移时很实用,避免因负数向下溢出导致关联失败。
另外,某些场景下用 FLOOR(x * 100) / 100 模拟保留两位小数截断(非四舍五入),但要注意浮点精度误差 —— 比如 1.235 * 100 在部分数据库中可能算出 123.49999999999999,FLOOR 后变 123,结果反而是 1.23 而非预期的 1.24。
性能与索引使用限制
FLOOR 和 CEILING 都是非确定性计算函数(实际是确定性的,但多数数据库优化器不将其识别为索引友好型表达式),因此 WHERE FLOOR(price) = 10 通常无法有效利用 price 字段上的 B-tree 索引。
更高效的做法是重写条件:
- ❌
WHERE FLOOR(amount) = 5 - ✅
WHERE amount >= 5 AND amount
同理,ORDER BY FLOOR(created_at / 3600)(按小时分组排序)会强制全表扫描;若需高频按小时聚合,建议提前物化小时字段并建索引。
真正容易被忽略的是:不同数据库对浮点输入的处理边界略有差异。例如 FLOOR(9223372036854775807.0 + 0.1) 在 64 位整数溢出临界点附近,SQLite 可能返回异常值,而 PostgreSQL 会静默转为 double precision 计算 —— 这类细节只有在处理时间戳毫秒值或大额金额时才会暴露。

















