Rails ActiveRecord“maximum(:column)”忽略顺序

时间:2014-04-23 12:10:14

标签: mysql ruby-on-rails activerecord

我正在尝试使用ActiveRecord检索列的最大值,但在我订购并限制值之后。

我的查询是:

max_value = current_user.books.order('created_at DESC').limit(365).maximum(:price)

然而,结果查询是:

(243.0ms)  SELECT MAX(`books`.`price`) AS max_id FROM `books` WHERE `books`.`user_id` = 2 LIMIT 365

订单被完全忽略,因此最大值来自前365个记录而不是最后365个记录。

4 个答案:

答案 0 :(得分:2)

活动记录代码(active_record / relation / computation.rb)中有一条奇怪的行,它删除了排序。我说好奇,因为它特指postgres:

# Postgresql doesn't like ORDER BY when there are no GROUP BY
relation = reorder(nil)

您应该可以使用pluck来达到您想要的效果。它可以选择一个属性,该属性可以是对聚合函数的引用:

q = current_user.books.order('created_at DESC').limit(365)
max_value = q.pluck("max(price)").first

pluck将返回一个值数组,因此您需要第一个获取第一个值(在这种情况下只有一个)。如果没有结果,那么它将返回nil。

答案 1 :(得分:0)

最好也是最有效的方法是做子查询......做这样的事情......

       current_user.books.where(id: current_user.books.order('created_at DESC').limit(365)).maximum(:price)

答案 2 :(得分:0)

根据rails guides maximum返回此字段的表的最大值,因此我认为Active Records会尝试优化您的查询并最终搞乱执行链式方法的顺序。

你可以试试:首先查询你想要的365行,然后获得最大值?

max_value = (current_user.books.order('created_at DESC').limit(365)).maximum(:price)

答案 3 :(得分:0)

我已经找到了解决方案,感谢freenode上的#RubyOnRails:

max_value = current_user.books.order('created_at DESC').limit(365).pluck(:price).max

当然缺点是这将获取所有365价格并在本地计算最大值。但我会活下来。