postgresql Runde Hälfte nach unten Funktion
die Runde(numeric,integer) - Funktion in PostgreSQL nur Runden bis:
round(cast (41.0255 as numeric),3) ==> 41.026
Da brauchen wir ein round-Funktion gibt 41.025 und (ganz überraschend) gibt es nicht so eine Funktion in PostgreSQL (wir verwenden 9.1.5), wir schrieben eine "wrapper" - Funktion, die in der ersten version ist ziemlich naiv und rauh...aber das haben wir nicht etwas besseres finden, durch die fehlende native Unterstützung für diese Art von Problemen in plpgsql.
Wird der code gezeigt unten. Das problem ist, dass es zu langsam für unsere Zwecke.
Könnten Sie vorschlagen, eine bessere Möglichkeit zur Bewältigung dieser Aufgabe?
Hier der code:
CREATE OR REPLACE FUNCTION round_half_down(numeric,integer) RETURNS numeric
AS $$
DECLARE
arg ALIAS FOR $1;
rnd ALIAS FOR $2;
tmp1 numeric;
res numeric;
BEGIN
tmp1:=arg;
IF cast(tmp1 as varchar) ~ '5$' THEN res:=trunc(arg,rnd);
ELSE res:=round(arg,rnd);
END IF;
RETURN res;
END;
$$ LANGUAGE plpgsql;
Muss ich cast den numerischen Wert und die Verwendung von regexp...das ist es, was (nehme ich an) tötet Leistungen.
Nur damit Sie wissen: wir brauchen das, weil wir haben einen Vergleich der zahlen, die gespeichert wurden, in zwei unterschiedlichen Spalten (auf zwei verschiedenen Tischen), aber mit verschiedenen numerischen Datentyp: eines mit Doppelbett und eines real ist. Das problem ist, dass beim einfügen in einen real-Datentyp-Spalte, PostgreSQL führt die RUNDE HÄLFTE nach UNTEN, während es keine solche option, über seine mathematische Funktionen!
EDIT:
Die Funktion ist tatsächlich verbuggt. War eine erste kurze umschreiben als ein Versuch zur Verbesserung der Leistungen in der Funktion arbeiten, aber sehr langsam.
Verhalten übereinstimmen muss, die folgenden Schritte aus:
IF
der Nachkommastelle gesetzt aus der Rundung ist <=5 => trunc
ELSE
Runden.
Einige Beispiele:
select round_half_down(cast (41.002555 as numeric),3) -- 41.002
select round_half_down(cast (41.002555 as numeric),4) -- 41.0025
select round_half_down(cast (41.002555 as numeric),5) -- 41.00255
während der round-Funktion in PostgreSQL gibt:
select round(cast (41.002555 as numeric),3) -- 41.003
- Möchten Sie
-41.0255
gerundet auf-41.025
oder-41.026
? Außerdem: Würden Sie wollen, dass41.02551
gerundet auf41.025
oder41.026
? - Hi @erwin-brandstetter, Die Funktion ist tatsächlich verbuggt. War ein erste-rewriting zur Verbesserung der Leistungen in der Funktion arbeiten, aber sehr langsam. Verhalten übereinstimmen muss, die folgende: WENN die Dezimalstelle wird put off von der Rundung ist <=5 => trunc ANDEREN in der Runde. Einige Beispiele: wählen Sie round_half_down(cast (41.002555 wie numerisch),3) -- 41.002 wählen Sie round_half_down(cast (41.002555 wie numerisch),4) -- 41.0025 wählen Sie round_half_down(cast (41.002555 wie numerisch),5) -- 41.00255 während der round-Funktion in postgresql: select round(cast (41.002555 wie numerisch),3) -- 41.003
- Ich aktualisiert meine Antwort entsprechend Ihrer updates. BTW, diese Art von Informationen sollten in deiner Frage, nicht in einem Kommentar, wo es zu Lesen ist hart.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieser sollte extrem schnell und einfach:
Grundsätzlich, nur Stimmen die
double precision
Nummerreal
für den Vergleich.Wenn das nicht für Sie arbeiten, diese SQL-Funktion, der sollte einen richtige job und Arbeit schneller:
Nun fest für negative zahlen, mit input von @sufleR in die Kommentare.
Sie können auch verwenden Sie einfach die enthaltenen
CASE
Ausdruck.% .. modulo-operator
^ .. Potenzierung
Hier ist ein kurzer test, den Sie verwenden können, für benchmarking:
Es zeigt auch, wie @Parveen Funktion und Ihre bearbeitete version verrechnen - Sie
trunc()
wo Sie nicht sollten.real
für Sie arbeiten oder die Funktion?CASE WHEN $1%0.1^$2
sollteCASE WHEN ABS($1%0.1^$2)
Methode ist sehr schnell, ohne eine neue FUNKTION, die Runde Hälfte nach unten wie folgt:
-- Runde die Hälfte bis
-- Runde Hälfte nach unten
Ist Es Ganz Einfach:
Versuchen, diese Funktion zu verwenden
Hier ist eine viel einfachere Ansatz
Können generische, durch ändern (0.001 für 3 dezimal, 0.0001 für 4 dezimal usw.)
HERAUSGEGEBEN von der OP:
@Parveel: habe ich geändert, die Funktion in der Reihenfolge zu make es die Arbeit in einer Allgemeinen Weise.
Versuchen, diese Hoffnung kann Ihnen helfen, u