2012-11-13 29 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中的计算 –