我今天遇到了一个问题,导致我陷入了 ActiveRecord 使用的陷阱。
ActiveRecord 为特定查询返回(包含)ActiveRelation 对象中一定数量的对象。
如果您链接同一个 ActiveRecord 查询 sum(:attribute)
,它会在计算结果中包含更多对象。为了描述我在这里的意思我的例子:
环境: 事件记录 4.2.3 Postgres 9.3.5
数据库结构:
订单有_多件商品
我的查询:
@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 在查询中没有发挥任何作用。如果我求和结果的价格,以 ruby 表示:
@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 的查询多得多的订单(重复)。
我希望这可以帮助您避免这个陷阱。
纳比纳布
最佳答案
includes
一般用于eager loading .为什么不用 joins
代替它?
关于ruby-on-rails - ActiveRecord SUM 在计算中包含的对象多于它提供没有求和的相同查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32078603/