FLOOR向下取整、CEIL向上取整,均返回BIGINT;不四舍五入,负数需注意方向(如CEIL(-2.1)=-2);常用于区间分组、分页计算等,但慎用于索引字段和高精度DECIMAL运算。

FLOOR 和 CEIL 函数的基本行为
FLOOR 向下取整,CEIL(或 CEILING)向上取整,都返回 BIGINT 类型结果。它们不四舍五入,也不受小数位数影响,只看数值方向:比如 FLOOR(3.9) 是 3,CEIL(-2.1) 是 -2(注意负数!向上取整是往数轴右侧走,不是“绝对值变小”)。
常见错误现象:
• 把 CEIL(-2.1) 误以为是 -3(实际是 -2)
• 对浮点字段直接取整后参与等值比较,因隐式类型转换导致索引失效
• 在 GROUP BY 或 ORDER BY 中混用未加括号的表达式,如 ORDER BY FLOOR(x/10) * 10 忘了括号,优先级出错
在聚合与分组中按区间归类数据
典型场景:把价格 price 按每 50 元一段分组统计(0–49、50–99、100–149…),用 FLOOR 最稳。
实操建议:
• 写成 FLOOR(price / 50) * 50,别用 CEIL 配减法,容易在边界上翻车
• 如果字段可能为 NULL,先 COALESCE(price, 0),否则整个表达式结果为 NULL
• 注意除法在 MySQL 中默认是浮点除,但 FLOOR 输入为 DECIMAL 也没问题,无需额外转类型
• 示例:
SELECT FLOOR(price / 50) * 50 AS price_range, COUNT(*) FROM products GROUP BY price_range;
和 ROUND 的关键区别:什么时候不能换
ROUND 是四舍五入,FLOOR/CEIL 是方向确定的截断。性能上三者几乎无差别,但语义不可互换。
容易踩的坑:
• 做分页计算总页数时,用 ROUND(total / size) 会少算页(比如 101 条 / 每页 10 条,ROUND(101/10)=10,但实际要 11 页),必须用 CEIL(total / size)
• 时间戳转小时粒度:想取“当前小时开始时间”,FLOOR(UNIX_TIMESTAMP(NOW()) / 3600) * 3600 安全;ROUND 可能在整点附近切错小时
• CEIL 对 DECIMAL 和 FLOAT 行为一致,但若输入是字符串(如 '3.7'),MySQL 会先转数字再计算——这步隐式转换可能触发警告,尤其开启严格模式时
兼容性与精度陷阱
MySQL 5.7+ 和 8.0 对 FLOOR/CEIL 行为一致,但要注意底层浮点表示误差可能放大。
实操建议:
• 避免对高精度 DECIMAL(18,10) 字段做多次除法后再 FLOOR,中间过程若被转成 DOUBLE(比如除以非整数),可能产生 0.999999999 这种值,FLOOR 就变成低 1 的结果
• 安全写法:显式转类型,如 FLOOR(CAST(x AS DECIMAL(20,10)) / 10)
• 在 WHERE 子句中慎用,例如 WHERE FLOOR(price) = 100 无法走 price 索引,应改写为 WHERE price >= 100 AND price
最常被忽略的一点:FLOOR 和 CEIL 返回的是整数类型,如果后续要拼接字符串或参与小数运算,记得显式 CAST(... AS DECIMAL),不然可能意外截断或触发隐式转换警告。










