Reputation: 17
Iwant to round of the value upto 2 decimal point when third decimal digit is greater then 5:
39.956 should be round off to 39.96,
35.665 should be round off to 35.66 ,
39.997 should be round off to 40.00 ,
56.684 should be round off to 56.68.
I am trying to do below
SELECT CAST(FLOOR(VALUE) AS VARCHAR2(30))
+ CASE
WHEN CAST(SUBSTR(SUBSTR(VALUE, INSTR(VALUE, '.')), 4) AS INT) > 5
THEN
CONCAT(
'.',
( SUBSTR(
SUBSTR(VALUE, INSTR(VALUE, '.')),
2,
2
)
+ 1)
)
ELSE
CONCAT(
'.',
SUBSTR(
SUBSTR(VALUE, INSTR(VALUE, '.')),
2,
2
)
)
END
FROM DUAL;
but for the border cases, for example 39.897 and 39.997 it is not working.
Upvotes: 1
Views: 353
Reputation:
Aleksej's solution will work fine and is probably the most efficient if it is known beforehand that the input numbers have at most three decimal places.
The problem can be generalized though, like so: round 38.445 down to 38.44; however, round 38.44503 to 38.45. (That is, if there are non-zero digits after the "5" in the third decimal position, then round up.)
Something like the query below can be used in the general case. The only time the result is different from "usual" rounding is when the input number has exactly three non-zero decimal places, and the third decimal place is 5. This is exactly how the solution reads.
with inp (n) as (select 38.445 from dual union all select 38.44503 from dual)
select n,
round(n,2) - case when n = round(n, 3) and mod(1000*n, 10) = 5
then 0.01
else 0 end as custom_rounded
from inp;
N CUSTOM_ROUNDED
---------- --------------
38.445 38.44
38.44503 38.45
Upvotes: 0
Reputation: 22949
Maybe you simply need this:
SQL> with test(num) as (
2 select 39.956 from dual union all
3 select 35.665 from dual union all
4 select 39.997 from dual union all
5 select 56.684 from dual
6 )
7 select num, round(num -0.001, 2)
8 from test;
NUM ROUND(NUM-0.001,2)
---------- ------------------
39,956 39,96
35,665 35,66
39,997 40
56,684 56,68
Upvotes: 2