ActiveRecord对子集或记录的计算
我有一个带有points
属性的Game
模型,我想计算前20个得分的总和。
我可以采取积分并让ruby计算总和,如:
Game.order('points desc').limit(20).pluck(:points).sum
但我很好奇是否有一种直接的方法让AR产生一个SQL聚合计算来实现同样的目的。 以下天真的尝试不起作用:
Game.sum(:points, order: 'points desc', limit: 20) SELECT SUM(`games`.`points`) FROM `games`
谢谢
试试这个:
Game.order('points desc').limit(20).sum(:points)
limit()在上面的答案中失败了
Game.order('point desc').limit(2).pluck(:point).inject(:+)
我将回答我自己的问题,但很乐意给出更好的解决方案。
sum
函数实际上只接受一个参数,而AR 4.x用于简单地忽略任何额外的args,新的AR 5.0.0会引发错误。 最初的尝试确实是天真的。
按照@pitabas的建议,我尝试了:
Game.order('points desc').limit(20).sum(:points) SELECT SUM("games"."points") FROM "games" LIMIT ? [["LIMIT", 20]]
从AR构造的SQL可以看出,这也不起作用,因为LIMIT
子句作用于查询的结果,该查询是单个值。 此外, ORDER
子句完全被忽略。 对于所有记录,上述表达式的结果是points列的总和。
实际工作的SQL查询类似于:
SELECT SUM(points) FROM (SELECT points FROM games ORDER BY points DESC LIMIT 20)
我最接近的是以下内容:
sq = Game.order('points desc').limit(20) Game.from(sq).sum('"points"')
产量:
SELECT SUM("points") FROM (SELECT "games".* FROM "games" ORDER BY points desc LIMIT ?) subquery [["LIMIT", 20]]
哈克:注意points
周围的双引号。 这就是我设法强制执行sum
参数的字面解释的方法。 没有它们,查询会引发“无此列”错误。
请注意,如果您只想计算总和,那么在订购结果时没有意义,那么下面的回答就足够了
Game.limit(10).sum(:points)