如何将平均往返PostgreSQL里的2位小数?(How to round an average t

2019-06-18 16:37发布

我通过红宝石宝石“的续集”使用PostgreSQL。

我试图四舍五入至小数点后两位。

这里是我的代码:

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

我得到以下错误:

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

我得到的,当我运行下面的代码没有错误:

SELECT ROUND(AVG(some_column))
FROM table

有谁知道我做错了吗?

Answer 1:

PostgreSQL不限定round(double precision, integer) 。 至于原因,@Catcall解释了评论,圆,需要一个精确的版本仅适用于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)

(在上面,注意float8仅仅是一个速记别名double precision 。你可以看到,是PostgreSQL扩展它的输出)。

你必须转换为四舍五入到值numeric使用的双参数形式round 。 只是追加::numeric的简写投,像round(val::numeric,2)


如果你格式化以显示给用户,不要用round 。 使用to_char (参见: 数据类型格式化功能手册中),它可以让你指定格式,并为您提供了一个text未受到任何怪事你的客户端语言可能会做的结果numeric值。 例如:

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

to_char将圆号码,你作为格式的一部分。 在FM前缀告诉to_char ,你不想与前导空格任何填充。



Answer 2:

也尝试旧的语法铸造,

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

PostgreSQL的任何版本的作品。

一些PostgreSQL的功能,为什么(???) 缺乏重载的 :(!),我认为“这是一个缺乏”,但@CraigRinger,@Catcall和PostgreSQL的团队同意关于“PG历史悠久的理由”。

PS:关于四舍五入的另一点是准确 ,检查@ IanKenney的答案 。


重载铸造策略

您可以超载与ROUND函数,

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

现在,您的指令将正常工作,尝试(函数创建后)

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

但它返回一个数字类型......为了保持第一黎民,使用过载,是提供了一个TEXT参数时,我们可以返回一个float类型,

 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;

尝试

 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:检查\df round超载后,会显示类似,

 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          

pg_catalog功能是默认的,看到的内置的数学函数手册 。



Answer 3:

试试这个:

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

或者干脆:

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


Answer 4:

据Bryan的回应,你可以做到这一点,以限制在查询小数。 我从千米/小时转换成米/秒,并在dygraphs显示,但是当我在dygraphs做到了它看起来怪异。 在查询中做计算的时候,而不是看起来不错。 这是PostgreSQL的9.5.1。

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


Answer 5:

错误:函数ROUND(双精度整数)不存在

解决方法 :您需要将AddType投那么它会工作

例如: round(extract(second from job_end_time_t)::integer,0)



文章来源: How to round an average to 2 decimal places in PostgreSQL?