【发布时间】:2010-07-19 14:21:32
【问题描述】:
我有一个应用程序可以存储每个锦标赛的玩家评分。所以我有多对多关联:
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 获取其父锦标赛,加载所有锦标赛参与者的参与(由rating desc 排序)并在此集合中获取自己的索引
然后是这样的:
player.participations.last.rank
我不喜欢的一件事 - 它需要加载锦标赛的所有参与,如果我需要最近 10 场锦标赛的玩家排名,它会加载超过 5.000 个项目(并且随着新玩家的添加,它的数量会增加)。
我相信应该有使用 SQL 的方法。实际上我尝试使用 SQL 变量:
find_by_sql("select @row:=@row+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 来说非常复杂)。
附:我正在使用 rails3.0.0.beta4
UPD:
这是获取玩家最后 10 个等级的最终 sql 请求(此外它还加载参与的锦标赛)
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;
【问题讨论】:
标签: sql ruby-on-rails activerecord