导读:本期聚焦于缅甸程序员创作的《Oracle的round、trunc、mod、ceil、floor函数怎么用?区别一次讲清》,敬请观看详情。同样是把3.456处理成一位小数,round给出3.5,trunc给出3.4;同样是取整,ceil遇到3.01返回4,floor遇到3.99却返回3。Oracle这五个高频数值函数的边界行为,恰恰是最容易出错的地方。本文用可直接执行的SQL示例逐个拆解round的四舍五入规则与负数位数用法、trunc的截断逻辑、ceil与floor的方向差异、mod在负数场景下的符号规则,并补充分页计算、金额抹零、奇偶判断等实战组合用法,帮你把这些函数的区别和适用场景一次理清楚。写SQL前把规则弄明白,能省掉不少排查数据误差的时间。

数值处理是SQL开发里出现频率极高的一类需求,Oracle提供的round、trunc、mod、ceil、floor这五个函数几乎覆盖了日常取整、舍入和取余的全部场景。它们语法都不复杂,但容易踩坑的地方藏在细节里:round对负数是往哪边舍入的?trunc截断负数时方向如何?mod在Oracle里对负数取余,结果符号跟谁走?这些问题不弄清楚,报表里差一分钱、分页时漏一页的情况就会反复出现。下面结合可以直接执行的示例,把这几个函数的行为规则和典型用法完整梳理一遍。

Oracle的round、trunc、mod、ceil、floor函数怎么用?区别一次讲清

一、round函数:四舍五入的规则与负数位数

round的完整语法是ROUND(n, integer),n是待处理的数值,integer指定舍入到的小数位数,不写时默认为0,也就是舍入到整数位。Oracle的round采用四舍五入、逢五远离零的规则,这一点和部分编程语言里的银行家舍入不同,做金额计算时尤其要注意。比如ROUND(2.5)的结果是3,ROUND(-2.5)的结果是-3而不是-2。

integer参数还可以传负数,表示舍入到十位、百位、千位,这是不少人没用过的特性,在数据汇总展示时非常实用,比如把销售额统一舍入到万元再出报表。看下面这组示例:

SELECT ROUND(3.14159, 2)  AS r1,   -- 结果 3.14
       ROUND(3.145, 2)    AS r2,   -- 结果 3.15
       ROUND(123.456, 0)  AS r3,   -- 结果 123
       ROUND(125.456, -1) AS r4,   -- 结果 130
       ROUND(123.456, -2) AS r5,   -- 结果 100
       ROUND(-2.5)        AS r6    -- 结果 -3
FROM dual;

从结果可以看出,保留两位小数时看第三位是否达到5;位数参数为-1时看个位,为-2时看十位,规则一致。还有一个容易被忽略的点:Oracle的number类型按十进制存储,ROUND(3.145, 2)能稳定得到3.15,不会像二进制浮点数那样在中间环节出现3.1449999之类的误差,这也是金额字段建议用number而不是binary_double的原因之一。另外,如果业务要求银行家舍入也就是逢五取偶,round满足不了,需要自己写case表达式处理,直接套round会造成系统性的单向偏差。

二、trunc函数:只砍不进的截断处理

trunc的语法和round一样是TRUNC(n, integer),但行为完全不同:它不做任何舍入,只是把指定位数之后的数字直接砍掉,方向永远朝零。对正数来说效果很直观,TRUNC(3.9999, 2)得到3.99;对负数则表现为朝零靠拢,TRUNC(-8.75)得到-8而不是-9,这一点必须和floor严格区分开。

SELECT TRUNC(3.9999, 2)   AS t1,   -- 结果 3.99
       TRUNC(-3.999, 2)  AS t2,   -- 结果 -3.99
       TRUNC(123.456, -1) AS t3,  -- 结果 120
       TRUNC(199.99, -2) AS t4,   -- 结果 100
       TRUNC(-8.75)      AS t5    -- 结果 -8
FROM dual;

和round对比着记更清楚:同样处理3.456保留一位小数,round看第二位是5就进位得3.5,trunc不管后面是什么直接砍成3.4。两者相差的这0.1在大量数据累加时会被放大,所以统计口径必须提前统一,是舍入还是截断要在需求阶段定死。trunc在业务里最常见的用途是金额抹零,比如财务要求金额只保留两位小数且不做四舍五入,用TRUNC(amount, 2)就比round更符合口径。

此外,trunc还是少数能同时处理日期的函数,TRUNC(SYSDATE)会把时间部分清零只保留日期,TRUNC(SYSDATE, 'mm')返回当月第一天,按天、按月做分组统计时经常和它打交道,很多按日汇总的报表底层都靠它来归一化时间。

三、ceil与floor:方向相反的一对取整函数

ceil和floor都只接收一个参数,语义很纯粹:ceil返回大于等于n的最小整数,也就是向上取整;floor返回小于等于n的最大整数,向下取整。正数场景没什么悬念,CEIL(3.01)是4,FLOOR(3.99)是3。真正的分水岭在负数:CEIL(-3.2)返回-3,FLOOR(-3.0001)返回-4,因为-3是大于等于-3.2的最小整数,-4是小于等于-3.0001的最大整数。记不清的时候在脑中画一条数轴,取整方向立刻就清楚了。

SELECT CEIL(3.0001)   AS c1,   -- 结果 4
       CEIL(3)        AS c2,   -- 结果 3
       CEIL(-3.2)     AS c3,   -- 结果 -3
       FLOOR(3.9999)  AS f1,   -- 结果 3
       FLOOR(-3.0001) AS f2,   -- 结果 -4
       FLOOR(-3)      AS f3    -- 结果 -3
FROM dual;

这两个函数最典型的应用是分页计算。假设总记录数为total,每页显示pageSize条,总页数应该写成CEIL(total / pageSize),这样99条数据按每页10条会正确算出10页;如果误用floor就会漏掉最后一页不满的数据。反过来,在计算满页数量、整块分配资源时用floor更合适,方向选错结果就差一整页或一整块。

ceil还经常和除法配合实现向上取整到某个倍数的需求。比如内存分配要凑整到100的倍数、物流计费按50公斤向上凑整,写法是CEIL(n / 100) * 100,对123来说结果是200。这种组合在容量规划、阶梯计费类需求里出现频率很高,比单纯记住ceil的取整规则更有实用价值。

四、mod函数:取余结果的符号规则

mod的语法是MOD(n2, n1),返回n2除以n1的余数。正数场景没有争议,MOD(10, 3)等于1。但Oracle的mod在负数上的行为和Java、C这类语言的百分号运算不一样:它基于floor语义计算,结果的正负号跟随除数n1。也就是说MOD(-10, 3)的结果是2而不是-1,因为-10除以3在floor语义下商取-4,余数算出来就是2。

SELECT MOD(10, 3)   AS m1,   -- 结果 1
       MOD(-10, 3)  AS m2,   -- 结果 2
       MOD(10, -3)  AS m3,   -- 结果 -2
       MOD(-10, -3) AS m4,   -- 结果 -1
       MOD(10, 0)   AS m5    -- 结果 10,除数为0时返回被除数
FROM dual;

还有一个细节:当除数为0时,mod不报错,而是直接返回被除数本身。这个设计在写通用逻辑时可以省去判空,但也可能掩盖问题,如果业务上除数本来就不应该为0,最好还是显式校验。mod的常见用法包括用MOD(id, 2)判断奇偶做隔行处理或分组,用MOD(rownum, 500)控制批量提交的节奏,以及按周期轮询拆分任务等。

五、五个函数的行为对比与组合用法

把五个函数放在一起对比,核心差异一目了然:

函数作用示例结果
round四舍五入,逢五远离零round(3.456, 1)3.5
trunc按位截断,方向朝零trunc(3.456, 1)3.4
ceil向上取整ceil(3.01)4
floor向下取整floor(3.99)3
mod取余,符号跟随除数mod(-10, 3)2

实际业务里它们经常组合出现。比如一张订单表要按客户统计金额,要求金额保留两位小数且抹零、平均值四舍五入到整数、按每页20条算总页数、订单号尾号奇偶分流,一条SQL就能完成:

SELECT customer_id,
       TRUNC(SUM(amount), 2)              AS total_amount,  -- 金额抹零,不做四舍五入
       ROUND(AVG(amount), 0)              AS avg_amount,    -- 平均值四舍五入到整数
       CEIL(COUNT(*) / 20.0)              AS total_pages,   -- 每页20条的总页数
       CASE WHEN MOD(order_id, 2) = 0
            THEN 'A通道' ELSE 'B通道' END  AS channel        -- 尾号奇偶分流
FROM t_order
GROUP BY customer_id;

这里有个小细节值得说明:Oracle的number除法默认保留小数,99除以20会得到4.95,所以CEIL(COUNT(*) / 20.0)能正确算出5页,把20写成20.0只是让意图更明显。金额口径统一用trunc还是round,取决于业务对误差的容忍方向,宁可少算一分还是多算一分,要在需求评审时就定死,不然月底对账时两边数字对不上,排查起来非常费劲。

总的来说,round管舍入、trunc管截断、ceil和floor管方向、mod管余数,五个函数各司其职。写SQL之前把负数行为和位数参数这些边界规则确认一遍,比出了问题再回头翻文档要省事得多。

Oracle数值函数round函数取整函数修改时间:2026-09-30 19:02:54

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0930/63938.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。