2014-05-14 23 views
1

我試圖在select語句中分兩列,然後將商四捨五入到小數點後4位。舍入一個分數的商數?

select round(round(sum(case when acct_no = '2999' 
     and date between '1/1/14' and current_date then amount end)::numeric, 4)::float 
/round(sum(case when acct_no = '3989' 
     and date between '1/1/14' and current_date then amount end)::numeric, 4)::numeric, 4) column 
from table 

查詢的其餘部分將保存多個日期,所以在那裏的日期應該是必要的。

它給錯誤:

ERROR: function round(double precision, integer) does not exist

這是試圖在PostgreSQL中。

+0

看起來應該可以工作!你是否嘗試投射而不是:: numeric,如:cast(... as numeric)?此外,你可以嘗試將'amount'合併爲0或某些東西(以防其返回null)(例如coalesce(amount,0 :: expectedtype)) – Greg

+0

截至目前它正在工作,但唯一的問題是它不是四捨五入。小數點後仍有14位數字。 – Padagomez

+1

這是因爲這輪比賽需要在師後進行。而不是個別的分子和分母。'round(round(sum(case when acct_no ='2999'and date between'1/1/14'and current_date then amount end):: numeric,4):: float /round(sum(case when acct_no =' 3989' 和'1/1/14'和current_date之間的日期,然後數量結束)::數字,4)::數字,4)'我認爲從本質上講,你說22.0000到4,然後是7.000到4,然後將兩個給... 3.1428571 ...但不要繞它。 – xQbert

回答

3

我重新格式化您的示例代碼,試圖更容易理解:

select round(
      round(
       sum(
        case 
         when acct_no = '2999' 
           and date between '1/1/14' and current_date then amount 
        end)::numeric, 
       4)::float 
      /round(
       sum(
        case 
         when acct_no = '3989' 
           and date between '1/1/14' and current_date then amount 
        end)::numeric, 
       4)::numeric, 
      4) column 
from table 

的問題是,你是您鑄造除法運算的分子作爲float數據類型,which, because you didn't specify a precision, is equivalent to double precision

round(
    sum(
     case 
      when acct_no = '2999' 
        and date between '1/1/14' and current_date then amount 
     end)::numeric, 
    4)::float 
/round(
    sum(
     case 
      when acct_no = '3989' 
        and date between '1/1/14' and current_date then amount 
     end)::numeric, 
    4)::numeric 

所以表達式的結果是一個double precision值而不是作爲一個numeric值,因此你所觀察到的誤差。

4
SELECT round((
      sum(CASE WHEN acct_no = '2999' 
       AND thedate between '2014-1-1' AND current_date THEN amount END) 
     /sum(CASE WHEN acct_no = '3989' 
       AND thedate between '2014-1-1' AND current_date THEN amount END) 
     )::numeric, 4) AS result 
FROM tbl; 
  • 沒有功能round()具有添加精度修飾符浮點類型的Postgres。僅限於numeric,as per documentation

  • 將浮點數除以numeric得到double precisionfloat8)。測試:你的計算結束

    SELECT 5::float/3::numeric -- result is double precision 
    
  • 回合一次。這更快,更準確。

  • 從不使用date作爲列名。它是標準SQL中的保留字和Postgres中的基本類型。

  • 最好在代碼中使用日期文字中的recommended ISO 8601 date format。無論設置和區域設置如何,這都會起作用,而您的本地格式會因不同的設置而中斷。

如果不是你提到的rest of the query,這可以進一步簡化:

SELECT round(( sum(CASE WHEN acct_no = '2999' THEN amount END) 
     /NULLIF(sum(CASE WHEN acct_no = '3989' THEN amount END), 0) 
     )::numeric, 4) AS result 
FROM tbl 
WHERE thedate between '2014-1-1'::date AND current_date; 

最後,這也是「除以0」的除數使用NULLIF()異常捕獲。