2011-11-11 17 views
7

私は、最大と最小のidのステータスによってグループ化を取得するために、例えば、一度に複数の集計関数をしたい:Rails/ActiveRecordで複数の集計関数を同時に使用するには?

Model.maximum(:id).minimum(:id).group(:status) 

(少なくともRailsの3.1.1で)このdoesntの仕事 - あなたは上のエラーを取得しますそれはFixnumで定義されていないと言っています。

NoMethodError: undefined method `minimum' for 22377:Fixnum 

私はそれのために生のSQLを行うことができます - しかし、より高いレベル/ Railsのオプションがある場合だけ不思議...

おかげで、クリス

私はこれがで可能であるとは思わない

答えて

13

、このようなことはできませんチェーン計算機能:ここで

は一例です。私は例えば、あなたが select述語でSQLを使用する必要がありますと思います。:

Model.select('MAX(id) AS `maximum`, MIN(id) AS `minimum`').group(:status) 

私はちょうど私自身のプロジェクトでこれをテストし、期待どおりに動作するように見えます。

+1

それは私には良く見えます。 –

3

スコープではなく値を返すため、これらの集計関数はdocsを参照してください。これらはすべてcalculateメソッドを使用しています。これは数値を返します。

 # File lib/active_record/calculations.rb, line 117 
117:  def calculate(operation, column_name, options = {}) 
118:   validate_calculation_options(operation, options) 
119:   column_name  = options[:select] if options[:select] 
120:   column_name  = '*' if column_name == :all 
121:   column   = column_for column_name 
122:   catch :invalid_query do 
123:   if options[:group] 
124:    return execute_grouped_calculation(operation, column_name, column, options) 
125:   else 
126:    return execute_simple_calculation(operation, column_name, column, options) 
127:   end 
128:   end 
129:   0 
130:  end 

これを行うには、手動でクエリを作成する必要があります。私は@topekが正しいと信じている

sql = "SELECT max(id) as max_id, 
       min(id) as min_id 
     FROM model 
     GROUP 
      BY status 
    " 
Model.find_by_sql(sql).each do |row| 
    puts "min. id: #{row.min_id}, " << 
     "max. id: #{row.max_id}, " 
end 
+0

OK-、そのためのおかげでよさそうです。 –

12

Rails 4でグループを使用して解決した同様の問題がありました。

Model.group(:status).pluck('min(id)','max(id)') 

また、注文など、および計算された列でも機能します。

Model.group('CAST(created_at AS Date), EXTRACT(HOUR FROM created_at), floor(EXTRACT(MINUTE FROM created_at)/15) * 15') 
    .having('count(id) > 10') 
    .order('min(created_at)') 
    .pluck('count(id)') 

乾杯

+0

ありがとう、これは素晴らしい作品です。 – jayant

関連する問題