如何在PostgreSQL中将平均值舍入到2位小数?

时间:2012-10-28 21:15:12

标签: sql postgresql sequel

我通过Ruby gem'续集'使用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

有谁知道我做错了什么?

7 个答案:

答案 0 :(得分:194)

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(请参阅手册中的data type formatting functions),它可以让您指定一种格式,并为您提供text结果,该结果不会受到您的客户语言可能对您做的任何奇怪的影响{ {1}}值。例如:

numeric
作为格式化的一部分,

regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00'); to_char --------------- 3.14 (1 row) 将为您舍入数字。 to_char前缀告诉FM您不希望任何带有前导空格的填充。

答案 1 :(得分:63)

还尝试使用旧的语法进行投射,

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

适用于任何版本的PostgreSQL。

在一些PostgreSQL函数中缺少重载,为什么(???):我认为"它是缺乏" (!),但@CraigRinger,@ Catall和PostgreSQL团队同意" pg的历史原理"。

PS:关于舍入的另一点是准确性,请检查@IanKenney's answer


重载为投射策略

您可以使用

overload使用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

但它返回一个NUMERIC类型...为了保留第一个commom-usage重载,我们可以在提供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函数是默认函数,请参阅manual of build-in math functions

答案 2 :(得分:27)

试试这个:

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

或者简单地说:

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

答案 3 :(得分:2)

根据Bryan's响应,您可以这样做以限制查询中的小数。我将km / h转换为m / s并将其显示在dygraphs中但是当我在dygraphs中执行它时它看起来很奇怪。在查询中进行计算时看起来很好。这是在postgresql 9.5.1上。

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

答案 4 :(得分:1)

尝试将列转换为数字,例如:

reverse'

答案 5 :(得分:0)

您可以使用下面的功能

 SELECT TRUNC(14.568,2);

结果将显示:

14.56

您还可以将变量转换为所需类型:

 SELECT TRUNC(YOUR_VAR::numeric,2)

答案 6 :(得分:0)

选择 ROUND(SUM(amount):: numeric,2)作为total_amount 从 交易

给出:200234.08