【问题标题】:ActiveRecord: Using the average of a related model in a queryActiveRecord:在查询中使用相关模型的平均值
【发布时间】:2014-10-28 18:13:40
【问题描述】:

我有一些 Rails 模型看起来有点像这样:

class Manufacturer
  has_many :widgets
end

class Widget
  belongs_to :manufacturer
  has_many :listings

  def weighted_average
    listings.sum('value * stock') / listings.sum('stock')
  end
end

class Listing
  # Represents that a merchant is selling some widgets
  belongs_to :widget
  belongs_to :merchant
  # Model has a :price, eg. $5.99
  # Also has a :stock, eg. 45 units
end

我现在要查找所有Listing 对象,其中Listing#value 低于它所属的Widgetweighted_average

例如,如果某个特定小部件的平均价格为 5 美元,并且有 4 美元、4.50 美元和 6 美元的列表,我想退回前两个 - 因为它们低于平均价格并且代表一个好交易。

该查询应生成所有小部件的所有低价商品列表,我希望能够在单个查询中完成此操作。

如何使用 ActiveRecord 查询来做到这一点?在理想的伪代码中,它会是这样的:

Listing.where('listing.price < widget.weighted_average')
# Not possible, because weighted_average isn't a column in the DB, but a method.

【问题讨论】:

  • 你试过了吗:Listing.where('price &lt; ?', widget.weighted_average)
  • widgets.sum('value * stock') / widgets.sum('stock') 是什么,或者更准确地说,weighted_average 方法中的 widgets 是什么?
  • 我希望它适用于多个小部件,而不仅仅是单个小部件的列表。上面的建议将为where 子句使用相同的值,而不是列表小部件的平均值。我也意识到我的意思是listings.sum,而不是widgets.sum - 我已经编辑了我的问题。

标签: sql ruby-on-rails rails-activerecord


【解决方案1】:

试试:

Listing.joins(:widget).where("#{Listing.table_name}.price < ?", 15)

编辑:

数字必须替换为您的加权平均函数结果。根据您使用的数据库,它可以是一个准确返回您想要的内容的 sql 查询。例如,对于 PostgreSQL,需要HAVING 子句。

【讨论】:

  • 我已将我的问题更新为更清晰 - 查询应生成所有小部件的所有低价列表的列表,我希望能够一次性完成询问。该数字是动态的,需要在查询中查找,而不是传入变量。
  • 然后看看HAVING 子句。
猜你喜欢
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 2018-06-07
  • 1970-01-01
相关资源
最近更新 更多