ceiling向上取整(负数向零靠近),floor向下取整(负数向负无穷靠近);二者不适用于四舍五入,应使用round;跨库需注意函数名(mysql/oracle用ceil)和类型转换要求。

CEILING函数总是向上取整,但要注意它返回的是比原数大的最小整数
比如 CEILING(3.1) 返回 4,CEILING(-2.9) 返回 -2——负数向上取整是向零方向靠近,不是“加1”。这点容易误解,尤其在计算折扣、分页页码或库存余量时出错。
常见错误现象:CEILING(5.0) 返回 5(不是 6),说明它只对小数部分起作用;如果字段本身是整数类型,CEILING 不会改变值。
- 使用场景:计算最少需要多少个标准包装箱(每箱装10件),用
CEILING(quantity / 10.0),注意除数必须带小数点,否则整数除法可能截断 - SQL Server 和 PostgreSQL 都支持
CEILING(),MySQL 中函数名是CEIL()(两者等价) - Oracle 中也支持
CEIL(),但不支持CEILING写法,跨数据库迁移时要检查函数名
FLOOR函数向下取整,负数行为和CEILING对称
FLOOR(3.9) 返回 3,FLOOR(-2.1) 返回 -3。关键点在于:它始终朝负无穷方向取整,不是简单去掉小数。
典型误用:想把金额四舍五入到元,却写成 FLOOR(amount + 0.5)——这在正数时看似可行,但遇到负数(如 -12.7)就会错成 -12(正确应为 -13),所以这种“手动模拟四舍五入”不可靠。
- 更安全的做法是用标准的
ROUND(),除非明确需要截断式取整 - 在分页查询中算起始行号时,常用
FLOOR((page_no - 1) * page_size),但注意page_no必须是数值型,字符串会导致隐式转换失败 - PostgreSQL 对
FLOOR()输入类型敏感:传入text会报错,需先::numeric转换
CEILING和FLOOR在不同数据库中的类型兼容性差异
这两个函数大多要求输入是数值类型,但各数据库对隐式转换的宽容度不同。
例如字段 price_str 存的是 '19.99' 字符串:
- SQL Server 可能自动转成 numeric,
CEILING(price_str)暂时不出错,但遇到'N/A'就崩溃 - PostgreSQL 严格报错:
function ceiling(text) does not exist,必须显式写CEILING(price_str::numeric) - MySQL 5.7+ 在严格模式下也会报错,建议统一用
CAST(price_str AS DECIMAL)包一层再调用
性能影响:隐式类型转换可能导致索引失效,尤其是 WHERE 条件里对字段用 FLOOR(my_col),基本无法走索引。
别直接用CEILING/FLOOR做四舍五入,ROUND才是正解
有人用 CEILING(x - 0.5) 或 FLOOR(x + 0.5) 模拟四舍五入,但边界情况极不稳定:比如 x = 2.5,FLOOR(2.5 + 0.5) = FLOOR(3.0) = 3 看似对,但 x = -2.5 时 FLOOR(-2.5 + 0.5) = FLOOR(-2.0) = -2,而数学上 -2.5 应该舍入到 -3(银行家舍入规则下可能不同,但至少不是 -2)。
真正可控的方式只有一个:ROUND(x, 0)。它由数据库底层实现,遵循当前会话的舍入规则(如 PostgreSQL 默认四舍五入,SQL Server 可受 SET ARITHABORT 影响)。
容易被忽略的是精度参数:有些业务需要保留一位小数再取整,比如运费计算,应写 CEILING(ROUND(weight * rate, 1)),而不是 CEILING(weight * rate)——浮点误差可能让 3.000000000000001 被错判为 4。










