it-swarm.com.de

Wie rundet man in PostgreSQL einen Durchschnitt auf 2 Dezimalstellen?

Ich benutze PostgreSQL über die Ruby gem 'Fortsetzung'.

Ich versuche auf zwei Dezimalstellen zu runden.

Hier ist mein Code:

SELECT ROUND(AVG(some_column),2)    
FROM table

Ich erhalte folgenden Fehler:

PG::Error: ERROR:  function round(double precision, integer) does 
not exist (Sequel::DatabaseError)

Ich erhalte keine Fehlermeldung, wenn ich den folgenden Code ausführe:

SELECT ROUND(AVG(some_column))
FROM table

Weiß jemand, was ich falsch mache?

148
user1626730

PostgreSQL definiert round(double precision, integer) nicht. Aus Gründen @ Mike Sherrill 'Cat Recall' , die in den Kommentaren erläutert werden, ist die Version von round, die eine Genauigkeit hat, nur für numeric verfügbar. .

regress=> SELECT round( float8 '3.1415927', 2 );
ERROR:  function round(double precision, integer) does not exist

regress=> \df *round*
                           List of functions
   Schema   |  Name  | Result data type | Argument data types |  Type  
------------+--------+------------------+---------------------+--------
 pg_catalog | dround | double precision | double precision    | normal
 pg_catalog | round  | double precision | double precision    | normal
 pg_catalog | round  | numeric          | numeric             | normal
 pg_catalog | round  | numeric          | numeric, integer    | normal
(4 rows)

regress=> SELECT round( CAST(float8 '3.1415927' as numeric), 2);
 round 
-------
  3.14
(1 row)

(Beachten Sie, dass float8 Nur ein Alias ​​für double precision Ist. Sie können sehen, dass PostgreSQL es in der Ausgabe erweitert.).

Sie müssen den zu rundenden Wert in numeric umwandeln, um die aus zwei Argumenten bestehende Form von round zu verwenden. Fügen Sie einfach ::numeric Für die Kurzform hinzu, wie round(val::numeric,2).


Wenn Sie die Anzeige für den Benutzer formatieren, verwenden Sie nicht round. Verwenden Sie to_char (Siehe: Datentyp-Formatierungsfunktionen im Handbuch), mit dem Sie ein Format angeben und ein text Ergebnis erhalten, das von nichts beeinflusst wird Verrücktheit Ihre Client-Sprache könnte mit numeric Werten tun. Zum Beispiel:

regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00');
    to_char    
---------------
 3.14
(1 row)

to_char Rundet die Zahlen für Sie im Rahmen der Formatierung. Das FM -Präfix teilt to_char Mit, dass Sie kein Auffüllen mit führenden Leerzeichen wünschen.

209
Craig Ringer

Versuchen Sie auch die alte Syntax für das Casting,

SELECT ROUND(AVG(some_column)::numeric,2)    
FROM table;

funktioniert mit jeder Version von PostgreSQL.

Es gibt einen Mangel an Überladungen in einigen PostgreSQL-Funktionen, warum (???): Ich denke "es ist ein Mangel" (!), Aber @ CraigRinger, @Catcall und das PostgreSQL-Team sind sich einig über die "historische Begründung von pg".

PS: Ein weiterer Punkt zur Rundung ist die Genauigkeit , überprüfen Sie @ IanKenneys Antwort .


Überladung als Casting-Strategie

Sie können Überladung die ROUND-Funktion mit,

 CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $$
    SELECT ROUND($1::numeric,$2);
 $$ language SQL IMMUTABLE;

Jetzt funktioniert Ihre Anweisung einwandfrei, versuchen Sie es (nach der Funktionserstellung)

 SELECT round(1/3.,4); -- 0.3333 numeric

aber es gibt einen NUMERIC-Typ zurück ... Um die erste Commom-Use-Überladung zu bewahren, können wir einen FLOAT-Typ zurückgeben, wenn ein TEXT-Parameter angeboten wird.

 CREATE FUNCTION ROUND(float, text, int DEFAULT 0) 
 RETURNS FLOAT AS $$
    SELECT CASE WHEN $2='dec'
                THEN ROUND($1::numeric,$3)::float
                -- ... WHEN $2='hex' THEN ... WHEN $2='bin' THEN... complete!
                ELSE 'NaN'::float  -- like an error message 
            END;
 $$ language SQL IMMUTABLE;

Versuchen

 SELECT round(1/3.,'dec',4);   -- 0.3333 float!
 SELECT round(2.8+1/3.,'dec',1); -- 3.1 float!
 SELECT round(2.8+1/3.,'dec'::text); -- need to cast string? pg bug 

PS: Überprüfung \df round nach Überladungen, zeigt so etwas wie,

 Schema | Name | Ergebnisdatentyp | Argumentdatentypen 
 ------------ + ------- + ------------------ + - -------------------------- 
 Myschema | runde | doppelte Präzision | doppelte Genauigkeit, Text, int 
 Myschema | runde | numerisch | doppelte Genauigkeit, int 
 pg_catalog | runde | doppelte Präzision | doppelte Genauigkeit 
 pg_catalog | runde | numerisch | numerisch 
 pg_catalog | runde | numerisch | numerisch, int 

Das pg_catalog Funktionen sind die Standardfunktionen, siehe Handbuch der eingebauten mathematischen Funktionen .

68
Peter Krauss

Versuchen Sie es mit diesem:

SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67

Oder einfach:

SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
29
atiruz

Entsprechend Bryans Antwort können Sie dies tun, um Dezimalstellen in einer Abfrage zu begrenzen. Ich konvertiere von km/h nach m/s und zeige es in Dygraphs an, aber als ich es in Dygraphs gemacht habe, sah es komisch aus. Sieht gut aus, wenn Sie stattdessen die Berechnung in der Abfrage ausführen. Dies ist in postgresql 9.5.1.

select date,(wind_speed/3.6)::numeric(7,1) from readings;
2
kometen

Fehler: Funktionsrunde (doppelte Genauigkeit, Ganzzahl) existiert nicht

Lösung: Sie müssen den Typ cast hinzufügen, damit dies funktioniert

Beispiel: round(extract(second from job_end_time_t)::integer,0)

1
user5702982

sie können die folgende Funktion verwenden

 SELECT TRUNC(14.568,2);

das Ergebnis zeigt:

14.56

sie können Ihre Variable auch in den gewünschten Typ umwandeln:

 SELECT TRUNC(YOUR_VAR::numeric,2)
0
info vif