2012-11-13 92 views
2

我想根據模型中的第二個變量計算我模型中某個變量的加權平均值,並且無法通過ActiveRecord找到一種方法。在聚合函數之前對ActiveRecord對象執行行操作

class Employer < ActiveRecord::Base 
    attr_accessible :name, :number_of_employees, :average_age 

    def self.wt_avg_age 
    #return sum(number_of_employee * average_age)/sum(number_of_employees) 
    end 
end 

在直SQL,我會用:

SELECT id, SUM(number_of_employees*average_age)/SUM(number_of_employees) 
FROM employer 
GROUP BY name  

我可以在一個雄辯的方式(即執行像這樣的一個ActiveRecord關係,沒有拉下獨立陣列和迭代通過每一個記錄得到我的分子)?我嘗試過使用.select(),.pluck()和sum()沒有任何運氣的不同組合。我無法讓ActiveRecord對象執行sumproduct。

+0

爲什麼你要使用的對象模型,其中簡單sql查詢會做什麼?爲這項工作使用正確的工具。 –

+0

'id'是唯一的。如果你用'id'進行分組,你就不會完成任何事情 - 它相當於'SELECT number_of_employees * average_age/number_of_employees FROM employer'。或許還有別的東西可以分組,或者這應該是單排結果? – PinnyM

+0

我編造了這個例子,所以我忽略了這個。我現在正在按名稱分組。我應該爲每個名字返回一個記錄。 – RedRobin2202

回答

1

你應該能夠做一些事情,如:

Employer.select("name, (SUM(number_of_employees*average_age)/SUM(number_of_employees)) as sum").group(:name) 

這將僱主情況下歸還給您,但他們將只擁有.name和.sum屬性。這將運行你想要的確切的SQL查詢。

0

取一試,也許它可以工作:

def self.wt_avg_age 
    a = Employer.sum("number_of_employee * average_age") 
    b = Employer.sum('number_of_employees') 
    a/b 
end 
1

它看起來像ActiveRecord::Calculations#sum需要一個塊:

# File activerecord/lib/active_record/relation/calculations.rb, line 92 
def sum(*args) 
    if block_given? 
    self.to_a.sum(*args) {|*block_args| yield(*block_args)} 
    else 
    calculate(:sum, *args) 
    end 
end 

(見http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum

所以,你可以嘗試:

def self.wt_avg_age 
    numerator = self.all.sum { |e| e.number_of_employee * e.average_age } 
    denominator = self.sum :number_of_employees 
    return numerator/denominator 
end 
+0

這就是我一直在尋找的東西。謝謝! – RedRobin2202

+0

第二個想法,這不給我的選擇按名稱分組,因此它不工作。 – RedRobin2202

+0

請注意,這不會通過SQL來進行ruby-land中的計算 –

相關問題