Oracle ROUND function rounds "half up" by default :
select 3.674 my_number,
round(3.674,2) round_on_number
from dual
union
select 3.675 my_number,
round(3.675,2) round_on_number
from dual
union
select 3.676 my_number,
round(3.676,2) round_on_number
from dual
;
MY_NUMBER ROUND_ON_NUMBER
---------- ---------------
3,674 3,67
3,675 3,68
3,676 3,68
I need to round "half down", which essentially means that I should get the following result instead :
MY_NUMBER EXPECTED_ROUND_ON_NUMBER
---------- ------------------------
3,674 3,67
3,675 3,67
3,676 3,68
It should be fast as I need to do this on millions of items.
I could probably detect if the number ends with a "5" and trunc that last digit in that case, round otherwise, but I have the feeling this will be inefficient (?)
Thank you ! David
The documentation shows you the algorithm used :
- If n is 0, then ROUND always returns 0 regardless of integer.
- If n is negative, then ROUND(n, integer) returns -ROUND(-n, integer).
- If n is positive, then
ROUND(n, integer) = FLOOR(n * POWER(10, integer) + 0.5) * POWER(10, -integer)
So you could modify the positive, non-zero version:
FLOOR(n * POWER(10, integer) + 0.4) * POWER(10, -integer)
^
eg for a fixed rounding, and ignoring zeros/negative for now:
with t (my_number) as (
select 3.674 from dual
union all select 3.675 from dual
union all select 3.676 from dual
)
select my_number,
floor(my_number * power(10, 2) + 0.4) * power(10, -2) as round_on_number
from t;
MY_NUMBER ROUND_ON_NUMBER
---------- ---------------
3.674 3.67
3.675 3.67
3.676 3.68
You could include zero/negative via a case expression; or write your own function to handle it more neatly.
Knock .001 from the value, then round as normal:
select round(my_number-.001,2)
from MyTable
For rounding to 3dp, change to -0.0001
, etc
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.