2016-07-06 7 views
1

Iwant zu Runde des Wertes bis zu 2 Komma, wenn die dritte Dezimalstelle größer als 5:individuelle Rundenlogik off in SQL

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 unter

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; 

zu tun versucht, aber für die Grenzfälle, zum Beispiel 39.897 und 39.997 funktioniert nicht.

Antwort

2

Vielleicht müssen Sie einfach:

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 
+0

für SELECT RUNDE (39.995,2) VON dual; es gibt 40, aber ich möchte, dass es nur 39,99 ist, wie ich in der Frage gefragt habe, wenn die dritte Dezimalziffer größer als 5 ist (d. h. von 6), dann möchte ich nur die zweite Dezimalziffer erhöhen. Es unterscheidet sich etwas von der ursprünglichen runden Logik ROUND (NUM, 2), –

+0

@Aleksej Ich denke, Sie sollten die "0,001" in den "runden" Anruf statt in die Daten setzen, um besser zu reflektieren, was getan werden muss . –

+0

@MinkuJha ändern Sie es in 'Runde (39.995-001, 2)' dh 'Runde (Wert-001,2)' –

0

Aleksej Lösung wird gut funktionieren und ist wahrscheinlich die effizienteste wenn es vorher bekannt ist, dass die Eingabe von Zahlen höchstens drei Dezimalstellen haben.

Das Problem kann jedoch wie folgt verallgemeinert werden: Runde 38,445 bis 38,44; jedoch, Runde 38,44503 bis 38,45. (Das heißt, wenn nach der "5" in der dritten Dezimalstelle Ziffern ungleich Null sind, dann aufrunden.)

So etwas wie die folgende Abfrage kann im allgemeinen Fall verwendet werden. Das einzige Ergebnis, das sich vom "normalen" Runden unterscheidet, ist, wenn die Eingangsnummer genau drei von Null verschiedene Nachkommastellen hat und die dritte Dezimalstelle 5 ist. Genau so liest die Lösung.

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 
+0

Gemäß meiner Anforderung über Logik funktioniert gut, Wenn die 3. Dezimalziffer größer als 5 ist, dann muss sie nur inkrementiert werden. 38,44503 sollte auf 38,44 abgerundet werden. –

+0

Interessant, aber völlig unlogisch. Es kann verschiedene Möglichkeiten geben, um 0,5 auf einen ganzzahligen Wert zu runden, entweder auf 0 oder auf 1, und beide sind gleichermaßen logisch, gültig und legitim. Es gibt keinen möglichen logischen Grund, 0.59 als ganze Zahl auf 0 anstatt 1 zu runden. In jedem Fall bot ich diese Lösung nicht unbedingt für Ihr Problem an, sondern für mögliche zukünftige Leser, die eine allgemeinere Lösung für das, was ich denke, benötigen würden die logischere Anforderung. – mathguy