ceil和floor是方向相反、行为确定的取整函数,不可互换或用round替代;ceil向正无穷取整(如ceil(-2.7)=-2),floor向负无穷取整(如floor(-3.1)=-4);跨数据库时函数名、参数类型及null处理需谨慎。

CEIL 和 FLOOR 是方向相反、行为确定的取整函数,不能互换,也不能用 ROUND 替代。 它们在跨数据库场景下行为一致,但参数类型、函数名拼写和隐式转换陷阱容易导致结果偏差或报错。
CEIL 返回 ≥ 输入值的最小整数(向正无穷取整)
它不是“加1”,而是找数轴上刚好能托住输入值的那个整数天花板。比如 CEIL(-2.7) 返回 -2,因为 -2 > -2.7,且没有比 -2 更小的整数能满足 ≥ -2.7;CEIL(0.001) 也返回 1 —— 只要不是整数,就进一档。
- SQL Server 只认
CEILING(),写CEIL()会直接报错 - PostgreSQL / MySQL 支持
CEIL()和CEILING(),但统一用CEILING()更稳妥 -
CEIL(NULL)返回NULL,若用于WHERE条件(如CEILING(price) > 100),整行会被过滤,需显式加AND price IS NOT NULL - 不支持小数位参数;如需“保留1位小数后向上取整”,得写成
CEILING(x * 10) / 10.0
FLOOR 返回 ≤ 输入值的最大整数(向负无穷取整)
它也不是“去小数”,而是找数轴上刚好能垫住输入值的那个整数地板。比如 FLOOR(-3.1) 返回 -4,因为 -4 FLOOR(5.0) 就是 5。
- 分组常用模式:
FLOOR(price / 50.0) * 50得到价格区间起点(如 99 → 50,149 → 100) - 必须写
50.0而非50:整数除法(如 PostgreSQL 中99 / 50)会截断为1,导致FLOOR(1) * 50 = 50看似对,但一旦 price=100,100 / 50 = 2(整除),而100 / 50.0 = 2.0才真正稳定 - 时间分桶同理:
FLOOR(EXTRACT(EPOCH FROM ts) / 3600)比DATE_TRUNC('hour', ts)更可控,但要注意时区是否已归一化
为什么不能用 ROUND 替代 CEIL 或 FLOOR?
ROUND() 是四舍五入,行为受数据库实现影响(如 MySQL/PG 默认银行家舍入,SQL Server 直接进一),且对边界值敏感:ROUND(2.5, 0) 在不同库可能得 2 或 3;而 CEILING(2.5) 永远是 3,FLOOR(2.5) 永远是 2。
- 分页计算必须用
CEILING(total / page_size):剩 1 条也要开新页,ROUND可能把 95/10=9.5 圆成 10(侥幸),但 91/10=9.1 就圆成 9(漏页) - 库存预警若用
ROUND(low_stock_threshold / 2)做安全缓冲,可能因舍入方向错误导致误告警 - 所有涉及“强制上限”或“强制下限”的业务逻辑,都该用
CEILING或FLOOR,而不是赌ROUND的行为
最容易被忽略的是除法精度:只要涉及 FLOOR 或 CEILING 的表达式里有除法,就先确认分母是不是浮点数;其次是负数场景下的直觉偏差——FLOOR(-3.1) 是 -4,不是 -3,这点在价格折扣、积分抵扣等负向计算中极易出错。











