Saltar al contenido

¿Cómo redondear un promedio a 2 lugares decimales en PostgreSQL?

Solución:

PostgreSQL no define round(double precision, integer). Por razones @Mike Sherrill ‘Retirada de gatos’ explica en los comentarios, la versión de round que toma una precisión solo está disponible para 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)

(En lo anterior, tenga en cuenta que float8 es solo un alias abreviado para double precision. Puede ver que PostgreSQL lo está expandiendo en la salida).

Debe lanzar el valor para redondear a numeric para usar la forma de dos argumentos de round. Solo adjunta ::numeric para el elenco taquigráfico, como round(val::numeric,2).


Si está formateando para mostrarlo al usuario, no use round. Usar to_char (ver: funciones de formato de tipo de datos en el manual), que le permite especificar un formato y le text resultado que no se ve afectado por cualquier rareza que pueda hacer el lenguaje de su cliente numeric valores. Por ejemplo:

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

to_char redondeará los números como parte del formateo. los FM el prefijo dice to_char que no desea ningún relleno con espacios iniciales.

Prueba también la antigua sintaxis de transmisión,

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

funciona con cualquier versión de PostgreSQL.

Hay una falta de sobrecargas. en algunas funciones de PostgreSQL, ¿por qué (???): Creo que “es una falta” (!), pero @CraigRinger, @Catcall y el equipo de PostgreSQL están de acuerdo sobre el “fundamento histórico de pg”.

PD: otro punto sobre el redondeo es precisión, verifique la respuesta de @ IanKenney.


Sobrecarga como estrategia de casting

Puede sobrecargar la función REDONDEAR con,

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

Ahora su instrucción funcionará bien, intente (después de la creación de la función)

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

pero devuelve un tipo NUMÉRICO … Para preservar la primera sobrecarga de uso de commom, podemos devolver un tipo FLOAT cuando se ofrece un parámetro TEXT,

 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;

Tratar

 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 

PD: comprobación df round después de las sobrecargas, mostrará algo como,

 Schema     |  Name | Result data type | Argument data types 
------------+-------+------------------+----------------------------
 myschema   | round | double precision | double precision, text, int
 myschema   | round | numeric          | double precision, int
 pg_catalog | round | double precision | double precision            
 pg_catalog | round | numeric          | numeric   
 pg_catalog | round | numeric          | numeric, int          

los pg_catalog Las funciones son las predeterminadas, consulte el manual de funciones matemáticas integradas.

Prueba con esto:

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

O simplemente:

SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *