Oracle的round()和trunc()是两类常用的数据处理函数,前者会对目标值进行四舍五入,后者则直接截断多余部分不做进位,二者在数值运算和日期处理中都有大量应用,但核心逻辑存在明显差异。

函数基本定义
round()函数的核心逻辑是按照指定的精度对数值或日期进行四舍五入,超出精度的部分会根据下一位数值决定是否进位。trunc()函数的核心逻辑是直接截断到指定精度,无论超出部分的值是多少,都不会进行进位操作。
数值处理场景对比
在数值处理场景下,两个函数的参数格式一致,都是函数名(数值, 精度),精度为正数时表示保留小数点后几位,为负数时表示对整数部分进行截断或进位。
round()数值处理示例
round()会对指定精度后的第一位数值进行判断,大于等于5则进位,小于5则舍去。
-- 保留2位小数,第三位小数是5,进位 SELECT ROUND(123.4567, 2) FROM DUAL; -- 返回123.46 -- 保留2位小数,第三位小数是4,舍去 SELECT ROUND(123.4547, 2) FROM DUAL; -- 返回123.45 -- 精度为-1,对十位进行四舍五入,个位是5进位 SELECT ROUND(134, -1) FROM DUAL; -- 返回130 SELECT ROUND(135, -1) FROM DUAL; -- 返回140
trunc()数值处理示例
trunc()直接截断到指定精度,不会做任何进位判断。
-- 保留2位小数,直接截断后面所有小数 SELECT TRUNC(123.4567, 2) FROM DUAL; -- 返回123.45 SELECT TRUNC(123.4547, 2) FROM DUAL; -- 返回123.45 -- 精度为-1,直接截断十位后的部分 SELECT TRUNC(134, -1) FROM DUAL; -- 返回130 SELECT TRUNC(135, -1) FROM DUAL; -- 返回130
日期处理场景对比
日期处理时,两个函数的格式为函数名(日期, 格式),格式参数指定截断或四舍五入的时间单位,比如年、月、日、小时等。
round()日期处理示例
round()对日期进行四舍五入时,会判断指定单位后的时间部分是否超过一半,超过则进位到下一个单位。
-- 对月份四舍五入,日期是16号,超过当月一半天数,进位到下月
SELECT ROUND(TO_DATE('2024-03-16', 'yyyy-mm-dd'), 'mm') FROM DUAL; -- 返回2024-04-01
-- 对月份四舍五入,日期是15号,未超过当月一半天数,保留当月
SELECT ROUND(TO_DATE('2024-03-15', 'yyyy-mm-dd'), 'mm') FROM DUAL; -- 返回2024-03-01
-- 对小时四舍五入,分钟是30,进位到下一小时
SELECT ROUND(TO_DATE('2024-03-01 12:30:00', 'yyyy-mm-dd hh24:mi:ss'), 'hh24') FROM DUAL; -- 返回2024-03-01 13:00:00
trunc()日期处理示例
trunc()对日期直接截断到指定单位,忽略后面的所有时间部分。
-- 截断到月份,直接返回当月第一天
SELECT TRUNC(TO_DATE('2024-03-16', 'yyyy-mm-dd'), 'mm') FROM DUAL; -- 返回2024-03-01
-- 截断到小时,直接返回当前小时的0分0秒
SELECT TRUNC(TO_DATE('2024-03-01 12:30:00', 'yyyy-mm-dd hh24:mi:ss'), 'hh24') FROM DUAL; -- 返回2024-03-01 12:00:00
核心差异总结
可以通过下表快速对比两个函数的核心区别:
| 对比维度 | round()函数 | trunc()函数 |
|---|---|---|
| 核心逻辑 | 按精度四舍五入,超出部分判断后决定是否进位 | 直接截断到指定精度,不做任何进位 |
| 数值处理 | 精度后第一位>=5则进位 | 无论精度后数值是多少,直接截断 |
| 日期处理 | 指定单位后的时间超过一半则进位到下一个单位 | 直接截断到指定单位,忽略后续所有时间 |
| 适用场景 | 需要近似值、符合四舍五入规则的场景 | 需要精确截断、不需要进位的场景 |
在实际开发中,需要根据业务需求选择对应的函数,如果需要对数据做近似处理就使用round(),如果需要保留原始数据的截断值就使用trunc(),避免因为函数选择错误导致计算结果不符合预期。