Comment arrondir une moyenne à 2 décimales dans PostgreSQL?

J’utilise PostgreSQL via la suite de Ruby gem.

J’essaie de arrondir à deux décimales.

Voici mon code:

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

Je reçois l’erreur suivante:

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

Je ne reçois aucune erreur lorsque je lance le code suivant:

 SELECT ROUND(AVG(some_column)) FROM table 

Est-ce que quelqu’un sait ce que je fais mal?

PostgreSQL ne définit pas le round(double precision, integer) . Pour des raisons que @Catcall explique dans les commentaires, la version du tour qui prend une précision n’est disponible que pour les données numeric .

 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) 

(Dans ce qui précède, notez que float8 n’est qu’un alias abrégé pour la double precision . Vous pouvez voir que PostgreSQL le développe dans la sortie).

Vous devez convertir la valeur à arrondir à numeric pour utiliser la forme à deux arguments de round . Il suffit d’append append ::numeric pour la dissortingbution abrégée, comme round(val::numeric,2) .


Si vous formatez pour l’affichage à l’utilisateur, n’utilisez pas le round . Utilisez to_char (voir: fonctions de formatage des types de données dans le manuel), qui vous permet de spécifier un format et de vous donner un résultat text qui ne soit pas affecté par l’étrangeté de votre langage client avec numeric valeurs numeric . Par exemple:

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

to_char arrondira les chiffres pour vous dans le cadre du formatage. Le préfixe FM indique à to_char que vous ne voulez pas de remplissage avec des espaces de to_char .

Essayez aussi l’ancienne syntaxe pour le casting,

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

fonctionne avec n’importe quelle version de PostgreSQL.

Il y a un manque de surcharge dans certaines fonctions de PostgreSQL, pourquoi (???): je pense que “c’est un manque” (!), Mais @CraigRinger, @Catcall et l’équipe de PostgreSQL s’accordent sur la “justification historique de pg”.

PS: un autre point concernant l’arrondissement est la précision , vérifiez la réponse de @ IanKenney .


La surcharge comme stratégie de casting

Vous pouvez surcharger la fonction ROUND avec

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

Maintenant, votre instruction fonctionne correctement, essayez (après la création de la fonction)

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

mais il retourne un type NUMERIC … Pour préserver la première surcharge d’utilisation, nous pouvons renvoyer un type FLOAT lorsqu’un paramètre TEXT est proposé,

  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; 

Essayer

  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 ssortingng? pg bug 

PS: vérifiant \df round après les surcharges, montrera quelque chose comme,

  Schéma |  Nom |  Type de données de résultat |  Types de données d'argument 
 ------------ + ------- + ------------------ + ---------- ------------------
  myschema |  ronde |  double précision |  double précision, texte, int
  myschema |  ronde |  numérique |  double précision, int
  pg_catalog |  ronde |  double précision |  double precision            
  pg_catalog |  ronde |  numérique |  numérique   
  pg_catalog |  ronde |  numérique |  numérique, int          

Les fonctions pg_catalog sont les fonctions par défaut, voir le manuel des fonctions mathématiques intégrées .

Essayez avec ceci:

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

Ou simplement:

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

Erreur: la fonction round (double précision, entier) n’existe pas

Solution : Vous devez append le type de dissortingbution puis cela fonctionnera

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

Selon la réponse de Bryan, vous pouvez le faire pour limiter les décimales dans une requête. Je convertis de km / h en m / s et l’affiche dans des graphes mais quand je l’ai fait dans des graphes, ça avait l’air bizarre. Cela semble bien lors du calcul dans la requête à la place. Ceci est sur postgresql 9.5.1.

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