【问题标题】:ActiveRecord SUM includes more objects in the calculation than it supplies the same query without sumActiveRecord SUM 在计算中包含的对象多于提供相同查询但没有 sum
【发布时间】:2015-08-18 17:08:27
【问题描述】:

我今天遇到了一个问题,导致我在使用 ActiveRecord 时遇到了问题。

ActiveRecord 为特定查询(带有包含)返回 ActiveRelation 对象中的一定数量的对象。 如果您链接同一个 ActiveRecord 查询 sum(:attribute),它会在计算结果中包含更多对象。为了描述我的意思,我的例子是:

环境: 活动记录 4.2.3 Postgres 9.3.5

数据库结构:

订购 has_many 项目

我的查询:

@orders = Order.includes(:items).where('orders.created_at >= ? AND orders.created_at <= ?', date_from, date_to)

生成的 SQL 查询:

SELECT orders.* FROM order_containers WHERE orders.created_at >= '2015-08-11' AND orders.created_at <= '2015-08-17 23:59:59.999999';

提到的查询返回例如20 个订单。如您所见,includes 不会在查询中播放任何规则。如果我对结果sum price,用红宝石表示:

@orders.to_a.sum(&:price)

返回 20.00

使用 SUM 进行相同的 ActiveRecord 查询:

Order.includes(:items).where('orders.created_at >= ? AND orders.created_at <= ?', date_from, date_to).sum(:price)

返回 45.00

它产生不同的 SQL 语句:

SELECT SUM(orders.price_eur) FROM orders LEFT OUTER JOIN line_items ON items.order_container_id = orders.id WHERE orders.created_at >= '2015-08-11' AND orders.created_at <= '2015-08-17 23:59:59.999999'

这种情况下的总订单数要多得多,因为生成的 SQL 查询不止一次包含相同的订单(因为加入)。每个订单都有一个或多个项目,这会导致比没有Left Outer Join的查询更多的订单(重复)。

我希望这可以帮助您避免这个问题。

纳比纳布

【问题讨论】:

  • 这很有趣,但也不是问题......
  • 是的,这不是一个真正的问题。我希望我能对我误解的事情得到解释。
  • 你有没有办法只用 SQL 来计算这个总和?

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


【解决方案1】:

includes 一般用于eager loading。你为什么不把它换成joins

【讨论】:

  • 我的目标是急切加载,正如您在条件中看到的那样。
  • 如果您使用连接或包含,它不会改变任何事情。结果保持不变。如果我使用连接,我会期待这样的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2020-03-17
相关资源
最近更新 更多