ruby-on-rails - ActiveRecord SUM 在计算中包含的对象多于它提供没有求和的相同查询

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

我今天遇到了一个问题,导致我陷入了 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/

相关文章:

ruby-on-rails - 静默的 ruby​​/rails 故障导致它消耗所有内存并使服务器崩溃

ruby-on-rails - 在 Rails 中建模这些关系的最佳方法

ruby-on-rails - Jasmine Rice on Rails 4

ruby - 了解 ruby​​ 中的 proc

SQL 连接子查询问题/性能

ruby-on-rails - ruby rails : Editor for backend of the web application

Ruby 日期参数超出范围

c - Postgresql C函数时间戳转换

ruby-on-rails - 在多个条件下使用 pg textsearch

ruby-on-rails - 使用 Koala::Facebook::GraphAPIMethods#put_connections 发布多张图片