ceil(-2.1)等于-2,因ceil返回≥当前值的最小整数,-2>-2.1且是满足条件的最小整数;floor(-2.1)等于-3,因floor返回≤当前值的最大整数,-3<-2.1且是满足条件的最大整数。

FLOOR 和 CEIL 在 MySQL 中不是“四舍五入”,也不是“去掉小数”,而是严格按数学定义做边界取整;用错会导致分页算少页、计费漏单、库存误判。
CEIL(-2.1) 为什么等于 -2?负数方向最容易踩坑
CEIL 返回 ≥ 当前值的最小整数,FLOOR 返回 ≤ 当前值的最大整数。负数时数轴方向不能按直觉理解:
- CEIL(-2.1) 是 -2(因为 -2 > -2.1,且是满足 ≥ -2.1 的最小整数)
- FLOOR(-2.1) 是 -3(因为 -3
- 把 CEIL(-2.1) 误写成 -3,通常是因为脑中代入了“绝对值变小”逻辑,但 SQL 不认这个
- 测试时务必覆盖负数用例:
SELECT CEIL(-2.1), FLOOR(-2.1)—— 结果必须是-2和-3
对 DECIMAL 或浮点字段直接取整可能触发隐式类型转换
MySQL 中 FLOOR 和 CEIL 总是返回 BIGINT,哪怕输入是 DECIMAL(10,2):
- 如果后续要参与等值比较(比如
WHERE FLOOR(price) = 10),MySQL 可能放弃使用price字段上的索引 - 更安全的做法是:先用范围判断替代等值,例如改写为
WHERE price >= 10 AND price - 若必须用取整结果做 JOIN 或 GROUP BY,建议提前在应用层或物化视图里计算并存为整型字段,避免每次查询都触发函数计算
- 注意
CEIL(9.0)返回9(BIGINT),不是9.0;和原始字段类型不一致时,别依赖自动补零
想保留 1 位小数再向上取整?标准 SQL 不支持 CEIL(col, 1)
MySQL 不接受多参数形式的 CEIL 或 FLOOR,所谓“保留 N 位小数后取整”必须手动缩放:
- 向上取整到 0.1:用
CEIL(col * 10) / 10.0(除数写10.0,不是10,否则整数除法会截断) - 向下取整到 0.01:用
FLOOR(col * 100) / 100.0 - 如果
col是字符串(如导出数据未清洗),先CAST(col AS DECIMAL(12,4)),否则报错function ceil(text) does not exist - 缩放后可能引入浮点误差(尤其在旧版 MySQL),建议对关键业务字段加
ROUND(..., 6)截断尾部噪声
分页总页数计算:CEIL(COUNT(*) / 10) 是对的,但要注意除法精度
常见写法 CEIL(COUNT(*) / 10) 在大多数场景可行,但有隐藏陷阱:
- MySQL 默认除法返回
DOUBLE,而CEIL对DOUBLE输入仍可靠;但若分母是变量(如参数@page_size),需确保它不是字符串或 NULL - 更健壮的写法:
CEIL(COUNT(*) / CAST(@page_size AS DECIMAL(10,0))) - 如果
@page_size可能为 0,必须前置判断,否则触发Division by zero错误 - 高并发下 COUNT(*) + CEIL 组合不适合实时分页总数展示,应考虑缓存或近似统计(如
TABLE_ROWS)
真正难的不是记住 CEIL(-2.1) = -2,而是当它嵌套在三层子查询 + JOIN 条件 + 分页偏移里时,你还得一眼看出边界是否被悄悄反转了。











