【发布时间】: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