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

use*_*730 165 sql postgresql sequel

我通过Ruby gem'seququel'使用PostgreSQL.

我想要舍入到小数点后两位.

这是我的代码:

SELECT ROUND(AVG(some_column),2)    
FROM table
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

PG::Error: ERROR:  function round(double precision, integer) does 
not exist (Sequel::DatabaseError)
Run Code Online (Sandbox Code Playgroud)

运行以下代码时,我没有收到任何错误:

SELECT ROUND(AVG(some_column))
FROM table
Run Code Online (Sandbox Code Playgroud)

有谁知道我做错了什么?

Cra*_*ger 224

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)
Run Code Online (Sandbox Code Playgroud)

(在上面,请注意这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)
Run Code Online (Sandbox Code Playgroud)

to_char作为格式化的一部分,将为您舍入数字.该FM前缀告诉to_char你不想与前导空格任何填充.

  • *"由于一些奇怪的原因,需要精度的回合版本仅适用于数字."*浮点数是"有用的近似值".如果您要求代码将浮点数舍入到两个小数位,返回*另一个*浮点数,则无法保证最接近"右"答案的近似值只有小数点右边的两位数.数字是有效缩放的整数; 他们没有那个问题. (9认同)
  • 对于那些试图通过@Catcall找到评论的人:现在是_Mike Sherrill'Cat Recall' (6认同)

Pet*_*uss 76

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

SELECT ROUND(AVG(some_column)::numeric,2)    
FROM table;
Run Code Online (Sandbox Code Playgroud)

适用于任何版本的PostgreSQL.

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

PS:关于舍入的另一点是准确性,请查看@ IanKenney的答案.


重载为投射策略

您可以重载 ROUND函数,

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

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

 SELECT round(1/3.,4); -- 0.3333 numeric
Run Code Online (Sandbox Code Playgroud)

但它返回一个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;
Run Code Online (Sandbox Code Playgroud)

尝试

 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 
Run Code Online (Sandbox Code Playgroud)

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函数是默认函数,请参阅内置数学函数手册.


ati*_*ruz 32

试试这个:

SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67
Run Code Online (Sandbox Code Playgroud)

或者干脆:

SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
Run Code Online (Sandbox Code Playgroud)

  • 我发现这是一个更简洁,更直接的前进,我对这个问题的回答.:弓: (3认同)
  • 同样在这里!非常简短且有用的解决方案。 (2认同)

Ada*_*Dev 11

你可以使用下面的功能

 SELECT TRUNC(14.568,2);
Run Code Online (Sandbox Code Playgroud)

结果将显示:

14.56
Run Code Online (Sandbox Code Playgroud)

您还可以将变量强制转换为期望类型:

 SELECT TRUNC(YOUR_VAR::numeric,2)
Run Code Online (Sandbox Code Playgroud)


Gab*_*Rua 9

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

SELECT ROUND(cast(some_column as numeric),2) FROM table
Run Code Online (Sandbox Code Playgroud)


小智 7

SELECT ROUND(SUM(amount)::numeric, 2) AS total_amount
FROM transactions
Run Code Online (Sandbox Code Playgroud)

给:200234.08