我有一个应用程序,用于存储每个锦标赛的玩家评分。所以我有很多-to-many关联:SQL:从查询中获取选定的行索引
Tournament
has_many :participations, :order => 'rating desc'
has_many :players, :through => :participations
Participation
belongs_to :tournament
belongs_to :player
Player
has_many :participations
has_many :tournaments, :through => :participations
的参与模式有一个rating
场(浮动)存储的评价值(它像得分点),每个玩家在每场比赛。
我想要的东西 - 获得玩家的最后10个等级(rank
是基于他的等级的特定比赛中的玩家的位置:更多等级 - 更高等级)。对于现在获得比赛我加载了本次比赛的所有参股玩家的排名,由rating
场对它们进行排序,并与Ruby代码得到了玩家的参与指数:
class Participation < ActiveRecord::Base
belongs_to :player
belongs_to :tournament
def rank
tournament.participations.index(self)
end
end
方法参与的rank
获得其父比赛中,加载所有tournamentr的参股(由rating desc
订购),并获得自己的索引这个集合里面
,然后是这样的:
player.participations.last.rank
的有一件事我不喜欢 - 它需要加载所有参加比赛的比赛,并且如果我需要最后10场比赛的球员排名,它会加载超过5000个项目(当新球员加入时它的数量会增加)。
我相信应该有办法为它使用SQL。其实我试图使用SQL变量:
find_by_sql("select @row:[email protected]+1 `rank`, p.* from participations p, (SELECT @row:=0) r where(p.tournament_id = #{tournament_id}) order by rating desc limit 10;")
此查询从给定的锦标赛中选择前10的评级。我一直试图修改它以选择给定用户和他的等级的最后10个参与者。
将不胜感激任何形式的帮助。 (我认为解决方案将是一个SQL请求,因为它对ActiveRecord来说非常复杂)。
P.S.我使用rails3.0.0.beta4
UPD:
这里是最终的SQL请求得到球员的最后10个等级(除了它加载参加比赛也一样)
SELECT *, (
SELECT COUNT(*) FROM participations AS p2
WHERE p2.tour_id = p1.tour_id AND p2.rating > p1.rating
) AS rank
FROM participations AS p1 LEFT JOIN tours ON tours.id = p1.tour_id WHERE p1.player_id = 68 ORDER BY tours.date desc LIMIT 10;
谢谢,这对我有用:) – 2013-07-25 06:42:11