【问题标题】:Limit query by sum of attributes of objects in Rails and Postgresql通过 Rails 和 Postgresql 中对象的属性总和限制查询
【发布时间】:2018-11-27 15:57:39
【问题描述】:

我有一个潜在客户模型,它有一个名为“sms_price”的预先计算的浮点列。我希望允许用户向这些潜在客户发送短信,并为他们的广告系列分配预算(类似于您在 Facebook 广告上可以找到的内容)。

我需要一个可以通过这些潜在客户的总价格来限制潜在客户数量的范围。例如,如果用户定义了 200 的总预算

  • id: 1 |短信价格:0.5 |总价格:0.5
  • id: 2 |短信价格:1.2 |总价:1.7
  • ID:3 |短信价格:0.9 |总价:2.6
  • ...
  • id: 94 |短信价格:0.8 | total_price: 199.4
  • id: 95 |短信价格:0.7 |总价:200.1

所以我需要在我的范围内做两件事:

  1. 递归计算总价
  2. 仅获取总价低于所需预算的潜在客户

到目前为止,我只使用这个范围完成了第一个任务(递归计算总价):

scope :limit_by_total_price, ->{select('"leads".*, sum(sms_price) OVER(ORDER BY id) AS total_price')}

这行得通,如果我这样做Lead.limit_by_total_price.last.total_price,我会得到38039.7499999615

现在我需要一种方法来仅检索总价低于预算的潜在客户:

scope :limit_by_total_price, ->(budget){select('"leads".*, sum(sms_price) OVER(ORDER BY id) AS total_price').where('total_price < ?', budget)}

但它不识别 total_price 属性:

ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "total_price" does not exist

为什么它可以识别单个对象中的 total_price 属性而不是范围?

【问题讨论】:

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5


【解决方案1】:

问题是在 SELECT 子句中计算的列不可用于同一语句中的 WHERE 子句。为了做你想做的事,你需要一个子查询。

您可以使用 ActiveRecord 的 from 方法执行此操作,但仍留在 Rails 世界中。该技术在this Hashrocket blog post 中有很好的说明。

在您的情况下,它可能看起来像这样(由于复杂性,我会使用类方法而不是范围):

def self.limit_by_total_price(budget)
  subquery = select('leads.*, sum(leads.sms_price) over(order by leads.id) as total_price')
  from(subquery, :leads).where('total_price < ?', budget)
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    相关资源
    最近更新 更多