2016-09-25 15 views
0

これまでにこれまでに遭遇したことはありません。私は浮動小数点/ intではなく、文字列であるテーブル属性を使って作業しています。値が文字列のときのテーブルの和の和

Model.first.amount => "58.00" 

私はすべての金額を合計する必要があります。私はamountがフロートされた状態で、に慣れて、次のようになります。

Model.all.sum(&:amount) => # total value 

がで野生の推測を取った:

Model.all.sum(&:amount.to_i) # undefined method `to_i' for :amount:Symbol 

量を合計するクリーンな方法はありますか?または、データベースをfloatに変換しますか?

+0

キャストはSELECT CAST( '1234' AS FLOAT)とする必要があります。 –

+0

金額は浮動小数点数を使用しないでください。 – Stefan

+0

私は知っています。私は誰かのデータベースと仕事をしています。彼らはそれを変えることを聞きません。 – Sylar

答えて

3

のRubyによる処理データベースはスーパーメモリが有効ではありません!

最初のショット:

Model 
    .pluck(:amount) # will fire sql 
    .sum(&:to_f) # convert to float, operating on resulting Array, not AR and sum 

しかし、データベースのデータを処理するための最も効果的な方法はもちろんのSQLです:

Model.sum("CAST(COALESCE(amount, '0') AS DECIMAL)") 
  1. ​​3210は'0'
  2. sumすべての値をnull値に置き換えられますDECIMALにキャスト。
+0

IIRCでは、精度を指定する必要があります。 'DECIMAL(10,2)' – Stefan

+0

@Stefan精度を指定するAFAIRはオプションです –

2

純粋なRubyでは、メソッドinjectを使用できます。

Model.all.inject(0) { |sum, object| sum += object.amount.to_i } 
+2

悪い考え方、多くのオブジェクトがある場合、このアプローチはメモリの過負荷につながります。 –

0

私はコメントする権限を持っていけないが、これは、ルビーのために働く必要があります。

Model.all.map(&:to_f).reduce(&:+) 
+0

これは機能しません。オブジェクト自体ではなく、amount属性の値を合計する必要があるからです。 Model.all.map(&:amount).map(&:to_f).reduce(&:+) ' –