2011-11-11 74 views
7

我想同時做幾聚合函數,如獲得最大和最小的ID通過狀態分組:如何在Rails/ActiveRecord中一次使用多個集合函數?

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

這不工作(至少使用Rails 3.1.1) - 你上了一個錯誤最低限度的通話,說它沒有定義在Fixnum上。

NoMethodError: undefined method `minimum' for 22377:Fixnum 

我能爲它做原料的SQL - 只是不知道是否有一個較高的水平/ Rails的選項...

謝謝,克里斯

回答

13

我相信@topek是正確的,你不能鏈的計算功能這樣的。我認爲你將不得不使用SQL在select謂詞,例如:

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

我只是測試這在我自己的一個項目,它似乎按預期方式工作。

+1

這對我來說更好 - 很好。 –

3

我不認爲這是可能的這些聚合函數,因爲它們返回一個值而不是範圍,請參閱docs。它們都使用的計算方法,正如你可以看到返回一個數字:

 # 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 

如果你想做到這一點,你必須製作手工查詢。

下面是一個例子:

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

我有一個類似的問題,我使用group 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

相關問題