ceil函数返回大于或等于输入值的最小整数,用于价格向上取整时严格进一(如19.001→20),不四舍五入;负数如-19.1返回-19;null输入返回null;mysql 5.7需用ceiling(),sqlite不支持需模拟;分位取整应写ceil(price*100)/100.0避免整数除法截断。

CEIL函数在价格计算中的基本行为
CEIL 是标准 SQL 数值函数,作用是「返回大于或等于输入值的最小整数」。对价格类字段(如 price、amount)做向上取整时,它不四舍五入,也不截断小数,而是严格进一——哪怕只有 0.001 也要变成下一个整数。
常见误用是把它和 ROUND 或 FLOOR 混淆:比如 CEIL(19.1) 得到 20,但 CEIL(20.0) 仍是 20,不会多加 1。
不同数据库中CEIL的写法与兼容性差异
绝大多数主流数据库都支持 CEIL,但拼写略有不同:
- PostgreSQL、MySQL 8.0+、SQL Server(2017+)、Oracle、Snowflake:直接用
CEIL() - MySQL 5.7 及更早版本:只认
CEILING(),CEIL()会报错Unknown function 'CEIL' - SQLite:不支持
CEIL,需用CAST(price AS INTEGER) + (CASE WHEN price > CAST(price AS INTEGER) THEN 1 ELSE 0 END) - BigQuery:支持
CEIL(),但注意输入为FLOAT64时可能有浮点精度问题,建议先ROUND(price, 2)再CEIL
处理带小数位的价格字段(如保留两位小数后向上取整)
实际业务中,常需要「先保留两位小数,再向上取整到元」,比如 19.995 → 保留两位是 20.00 → 向上取整仍是 20;但 19.001 → 保留两位是 19.00 → 向上取整还是 19。如果目标是「分位向上取整到元」,就得先乘 100,CEIL,再除 100:
SELECT CEIL(price * 100) / 100.0 AS price_ceil_2dp FROM orders;
关键点:
- 必须用
100.0而非100,避免整数除法导致结果被截断(如 PostgreSQL 中2000/100是20,但2000/100.0才是20.0) - 如果原始
price是DECIMAL(10,4)类型,乘除后仍保持精度;若为FLOAT,建议先ROUND(price, 4)消除浮点误差 - 某些场景要「分位进一」而非「元位进一」,例如 19.991 元应变成 20.00 元,此时用
CEIL(price * 100) / 100.0正确;若误用CEIL(price),19.991 会直接变 20,丢失了「以分为单位」的语义
CEIL与NULL、负数、字符串的交互风险
价格字段若含空值或异常数据,CEIL 行为容易引发静默错误:
-
CEIL(NULL)永远返回NULL,不会报错,但下游应用可能因空值崩溃——务必配合COALESCE(price, 0)或WHERE price IS NOT NULL -
CEIL(-19.1)返回-19(不是 -20),因为 -19 是「大于 -19.1 的最小整数」。价格字段极少为负,但如果来自退款或冲正数据,需额外判断符号:CASE WHEN price - 若
price是字符串类型(如'19.99'),多数数据库会隐式转数字,但 SQLite 和部分旧版 MySQL 会直接报错datatype mismatch或返回 0 —— 必须显式用CAST(price AS NUMERIC)或TRY_CAST(SQL Server)兜底
真正容易被忽略的是浮点表示误差:比如 0.29 + 0.01 在二进制浮点下可能存为 0.30000000000000004,CEIL 后变成 1 而非预期的 0。涉及加减运算的价格,优先用 DECIMAL 类型存储,或在 CEIL 前加一层 ROUND(..., 10) 截断尾差。











