簡體   English   中英

如何在PostgreSQL中將平均值四舍五入到小數點后兩位?

[英]How to round an average to 2 decimal places in PostgreSQL?

我正在通過 Ruby gem 'sequel' 使用 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

有誰知道我做錯了什么?

PostgreSQL 沒有定義round(double precision, integer) 由於@Mike Sherrill 'Cat Recall'在評論中解釋的原因,采用精度的 round 版本僅適用於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您不需要任何帶有前導空格的填充。

還可以嘗試使用舊語法進行轉換,

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

但它返回一個 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函數是默認函數,請參閱 內置數學函數手冊

試試這個:

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

或者干脆:

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

你可以使用下面的功能

 SELECT TRUNC(14.568,2);

結果將顯示:

14.56

您還可以將變量強制轉換為期望類型:

 SELECT TRUNC(YOUR_VAR::numeric,2)

嘗試將您的列轉換為數字,例如:

SELECT ROUND(cast(some_column as numeric),2) FROM table
SELECT ROUND(SUM(amount)::numeric, 2) AS total_amount
FROM transactions

給:200234.08

根據Bryan 的回復,您可以這樣做以限制查詢中的小數。 我將 km/h 轉換為 m/s 並將其顯示在 dygraphs 中,但是當我在 dygraphs 中進行時,它看起來很奇怪。 在查詢中進行計算時看起來不錯。 這是在 postgresql 9.5.1 上。

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

錯誤:函數round(雙精度,整數)不存在

解決方案:您需要添加類型轉換然后它會起作用

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM