簡體   English   中英

使用sum函數時如何避免PG :: NumericValueOutOfRange

[英]How to avoid PG::NumericValueOutOfRange when using sum function

我有這樣的方法:

  def self.weighted_average(column)
    sql = "SUM(#{column} * market_cap) / SUM(market_cap) as weighted_average"
    Company.select(sql).to_a.first.weighted_average
  end

當列是decimal ,它返回一個沒有問題的值。 但是當列是integer ,該方法最終會出現PG::NumericValueOutOfRange錯誤。

我應該將列類型integer更改為decimal ,還是有辦法在不更改列類型的情況下獲得sum的結果?

你總是可以從整數中float

  def self.weighted_average(column)
    column = column.to_f
    sql = "SUM(#{column} * market_cap) / SUM(market_cap) as weighted_average"
    Company.select(sql).to_a.first.weighted_average
  end

我建議你將數據類型更改為decimal 因為,當SUM獲取PG::NumericValueOutOfRange ,這意味着您的數據類型不足。 它將導致優雅地處理此方案,而不是解決方法。

您可以將值轉換為小數值,因此無需更改列類型:

sql = "SUM(#{column} * CAST(market_cap as decimal(53,8))) / SUM(CAST(market_cap as decimal(53,8))) as weighted_average"

PS我會改變列類型 - 它是一致的

Postgres文檔說這個關於SUM()返回類型:

smallint或int參數的bigint,bigint參數的numeric,否則與參數數據類型相同

這意味着您將以某種方式需要更改傳遞給SUM的數據類型。 它可以是以下之一:

  • 更改表以更改列數據類型。
  • 將列轉換為方法中的其他數據類型。
  • 創建一個視圖,將所有整數列轉換為數字,並在方法中使用它。

您正在嘗試將十進制值放入整數參數。 除非您使用無法實現的ABS()值,否則除非您100%確定%值始終為0。

如果您必須擁有INT,請使用類型Float或函數ABS()

喲可以嘗試將列轉換為十進制

sql = "SUM(CAST(#{column}) AS DECIMAL * market_cap) / SUM(market_cap) as weighted_average"

暫無
暫無

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

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