FLOOR返回向下取整(朝负无穷),CEIL返回向上取整(朝正无穷);例如FLOOR(2.9)=2、FLOOR(-2.1)=-3,CEIL(2.1)=3、CEIL(-2.9)=-2,二者均非四舍五入,且在所有主流SQL方言中行为一致。

FLOOR 和 CEIL 到底返回什么,别被“四舍五入”带偏
它们根本不做四舍五入:FLOOR 永远向下取整(朝负无穷),CEIL 永远向上取整(朝正无穷)。比如 FLOOR(2.9) 是 2,FLOOR(-2.1) 是 -3;CEIL(2.1) 是 3,CEIL(-2.9) 是 -2。很多初学者误以为 CEIL 是“进一”,结果在负数上栽跟头。
- 正数场景下,
FLOOR相当于截断小数部分,CEIL是“有小数就加1” - 负数才是关键分水岭:-2.1 的“向下”是 -3,不是 -2;数据库不会按人脑直觉判断方向
- 所有主流 SQL 方言(PostgreSQL、MySQL、SQL Server、Oracle)行为一致,无需担心兼容性差异
什么时候该用 FLOOR 而不是 CAST 或 ROUND
当你需要确定的、方向明确的整数边界时,FLOOR 比 ROUND 更可靠,比 CAST(x AS INTEGER) 更安全。例如计算分页起始行号:OFFSET FLOOR((page_no - 1) * page_size) —— 这里不能用 ROUND,否则第 0.9 页可能跳到第 1 页起点;也不能直接 CAST,因为某些方言(如 PostgreSQL)对负数的 CAST 是向零截断,和 FLOOR 不等价。
-
ROUND(2.5)可能是 2 或 3(取决于实现),FLOOR(2.5)永远是 2 -
CAST(-2.7 AS INTEGER)在 PostgreSQL 返回 -2,在 SQL Server 返回 -2,但语义不清晰;FLOOR(-2.7)明确是 -3 - 性能上无差别,三者都是标量函数,执行计划里都显示为 Compute Scalar
CEIL 的典型用途:资源配额与分组计数
CEIL 最常出现在“不够一单位也要算一单位”的业务逻辑里,比如按 100 条/批次切分任务,150 条要分 2 批,而不是 1 批——这时 CEIL(total_count / 100.0) 就比 (total_count + 99) / 100 更易读且跨方言安全。
- 务必写成
CEIL(x / 100.0)而不是CEIL(x / 100):整数除法在 MySQL/PostgreSQL 中会先截断,导致CEIL(150 / 100)=CEIL(1)= 1(错!) - Oracle 支持
CEIL,但旧版本不支持小数除法自动转浮点,显式写100.0更稳妥 - 如果字段本身是整型,除法前加
1.0 *或CAST(x AS DECIMAL)都可以,但1.0 *更轻量
容易忽略的 NULL 和类型隐式转换陷阱
FLOOR 和 CEIL 遇到 NULL 直接返回 NULL,这没问题;但真正容易出错的是输入值类型。比如把字符串传进去:FLOOR('12.34') 在 PostgreSQL 会报错,MySQL 会静默转成 12,SQL Server 则直接失败。
- 永远检查上游字段类型,尤其从 JSON 或外部导入的数据,
CAST(col AS NUMERIC)再进FLOOR更安全 - 在 WHERE 或 JOIN 条件中用
FLOOR(x) = 5时,注意索引失效风险:除非你建了函数索引(如 PostgreSQL 的CREATE INDEX ON t (FLOOR(x))),否则无法走 x 上的普通索引 - 如果只是想过滤“x 属于第 5 组”,更高效写法是
x >= 5 AND x ,而非依赖函数计算
实际用的时候,最麻烦的往往不是函数本身,而是除法精度和 NULL 传播链——一个没 cast 的字符串字段,经过两层子查询后才进 FLOOR,错误可能藏得很深。

















