根据属性有条件地计算平均值



我有一个要求,我需要根据产品的销售公司计算产品的平均销售单位。从那里我将计算与销售单位的百分比差异。有一个模型中有产品。每个产品都具有以下属性:

  • product_name
  • 单位销售额
  • 公司

有很多公司。

这段代码适用于计算所有记录的平均值,但我希望根据属性"company"有条件地计算平均值。

def average_UnitSold
    self.class.average(:unit_sold)
  end
def averagechange_UnitSold
      (self.unit_sold - average_UnitSold) / average_UnitSold * 100
  end

我想出了这个,但它不起作用:

def average_UnitSold
      self.class.sum(:unit_sold), :conditions => "company = self.company")) / :unit_sold
    end

有什么想法吗?

另一方面,将所有这些平均值存储在某个地方并只每天更新的更可行的方法是否更有效?

基于这个答案,我现在已经实现了这个代码,它似乎可以工作:

 def self.average_unit_sold(company)
   where(company: company).average(:unit_sold)
 end
 def average_unit_sold
          self.class.average_unit_sold(self.company)
        end
 def averagechange_UnitSold
      (self.unit_sold - average_unit_sold) / average_unit_sold * 100
  end

在实例方法中执行此操作非常奇怪,因为结果实际上与特定实例无关。相反,定义一个类方法:

class Product < ActiveRecord::Base
  # `self.average_unit_sold` is a class method that takes `company` as an
  # argument and executes an SQL query like this (where 'some_company' is the
  # company given in the argument):
  #
  #     SELECT AVG(products.unit_sold) FROM products
  #       WHERE products.company = 'some_company'
  #
  def self.average_unit_sold(company)
    where(company: company).average(:unit_sold)
  end
end
# ...then...
Product.average_unit_sold(some_company)

如果真的想要一个实例方法,可以添加一个(但将逻辑保留在类方法中):

# `average_unit_sold` is an instance method that takes the value of the 
# instance's own `company` attribute and calls `Product.average_unit_sold`:
def average_unit_sold
  self.class.average_unit_sold(self.company)
end

(这也可能是scope,但出于美观的原因,我更喜欢只在结果是模型实例或实例集合时使用作用域,而这里的情况并非如此。)

假设您已经正确设置了关联,这很容易实现。因此,假设一家公司有许多产品:

class Company < ActiveRecord::Base
  has_many :products
end
class Product < ActiveRecord::Base
  belongs_to :company
end

所有公司的平均销售量:

Product.average(:unit_sold)

一家公司的平均销售量:

company = Company.find(1)
company.products.average(:unit_sold) 

最新更新