I have method like this:
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
When the column is a decimal
, it returns a value without problem.
But when the column is integer
, the method ends up with a PG::NumericValueOutOfRange
error.
Should I change column type integer
to decimal
, or is there a way to get the result of sum
without changing column type?
You can always make float
from your integer.
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
You can cast your value to alway be a decimal value, thus no need to change the column type:
sql = "SUM(#{column} * CAST(market_cap as decimal(53,8))) / SUM(CAST(market_cap as decimal(53,8))) as weighted_average"
P.S. I would go with changing the column type - it is consistent then.
I would suggest you to change the datatype to decimal
. Because, when SUM gets PG::NumericValueOutOfRange
, it means that your datatype is not sufficient. It will lead to gracefully handle this scenario, instead of a workaround.
Postgres documentation says this about SUM() return type:
bigint for smallint or int arguments, numeric for bigint arguments, otherwise the same as the argument data type
This means that you will somehow need to change datatype that you pass to SUM. It can be one of the following:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With