CEIL返回≥当前值的最小整数,FLOOR返回≤当前值的最大整数;负数时CEIL(-2.1)=-2、FLOOR(-2.1)=-3;二者对NULL返回NULL,与DECIMAL配合需注意精度和类型转换,非四舍五入函数。

CEIL 和 FLOOR 的行为差异必须看懂
它们不是四舍五入,也不是“向上/向下取整到个位”这么简单——CEIL 总是返回 ≥ 当前值的最小整数,FLOOR 总是返回 ≤ 当前值的最大整数。负数场景最容易翻车。
-
CEIL(-2.1)返回-2(不是-3),因为 -2 是大于 -2.1 的最小整数 -
FLOOR(-2.1)返回-3(不是 -2),因为 -3 是小于 -2.1 的最大整数 - 对正数影响不大:
CEIL(2.1)→3,FLOOR(2.9)→2 - 如果字段含
NULL,两个函数都返回NULL,不报错但可能漏数据
在 GROUP BY 或聚合计算中直接用会出错
MySQL 5.7 严格模式下,若 SELECT 列包含非聚合字段又没出现在 GROUP BY 中,即使你只对某列用了 CEIL,也可能触发 ONLY_FULL_GROUP_BY 错误。
- 错误写法:
SELECT CEIL(price), name FROM products GROUP BY CEIL(price)——name未聚合也未分组 - 正确做法:要么把
name加进GROUP BY,要么用聚合函数包裹,如MAX(name) - 更安全的替代:先子查询处理取整,再外层分组,避免表达式干扰分组逻辑
和 DECIMAL 类型一起用要注意精度截断
CEIL 和 FLOOR 返回类型跟输入一致,但如果输入是 DECIMAL(10,2),结果仍是 DECIMAL,小数位数保留为 0,但底层仍按原精度存储——这在后续参与加减或比较时可能引发隐式转换问题。
-
SELECT CEIL(CAST(123.45 AS DECIMAL(10,2)))返回124.00(不是124) - 若想得到纯整数,显式转类型:
CAST(CEIL(x) AS SIGNED)或CONVERT(CEIL(x), SIGNED) - 在 ORDER BY 中混用
FLOOR(price * 10) / 10做价格区间分组时,注意 DECIMAL 运算可能多出微小误差,建议统一用ROUND(x, 1)配合FLOOR
替代方案:需要四舍五入别硬套 CEIL/FLOOR
很多人想“向上取整到十位”,就写 CEIL(x / 10) * 10,这没错;但若目标是“四舍五入到百位”,CEIL 就完全不合适了——它永远只向上,不会看小数部分大小。
- 四舍五入到百位:用
ROUND(x, -2),不是CEIL或FLOOR - 向零取整(即截断小数):MySQL 没内置函数,可用
TRUNCATE(x, 0),比FLOOR对负数更符合直觉 - 性能上无显著差别,但
ROUND在高并发统计中更常被缓存优化,CEIL/FLOOR更适合明确边界判断场景,比如分页起始位置计算:(page_no - 1) * page_size本身已是整数,无需再套一层
真正容易被忽略的是:当字段来自 JOIN 后的临时结果集,或嵌套子查询中带函数时,MySQL 可能无法使用索引加速 CEIL/FLOOR 计算——哪怕原始字段有索引。这时候取整逻辑最好前置到应用层,或改用范围条件代替函数调用。


















