Oracle SQL - Round - Half

末鹿安然 提交于 2019-12-13 16:58:24

问题


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


回答1:


The documentation shows you the algorithm used:

  1. If n is 0, then ROUND always returns 0 regardless of integer.
  2. If n is negative, then ROUND(n, integer) returns -ROUND(-n, integer).
  3. 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)
                                 ^

e.g. 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.




回答2:


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



来源:https://stackoverflow.com/questions/48279641/oracle-sql-round-half

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!