如何获取rails查询中每个组的最后第n条记录

时间:2017-07-16 09:08:56

标签: ruby-on-rails activerecord group-by

我有一张名为Game的牌桌,其中充满了nhl赛季所有比赛中的个人球员名单。我在这里关注的领域是games_played,其中n为本赛季球员的第n场比赛。 和名称是球员的名字。

基本上我正试图弄清楚如何为每位球员抓住第n场比赛。

例如我知道以下查询可以让我获得每个玩家的最后一个游戏

Game.group(:name).having('games_played = MAX(games_played)')

然而,当我尝试以下时(假设n是10)

Game.group(:name).having('games_played=MAX(games_played)-10')

我没有结果

事实上,如果我明确地做了像

这样的事情
Game.group(:name).having('games_played=16')

我只获得了最后一场比赛的16场比赛,而不是所有球员的第16场比赛。 (我猜这解释了之前查询没有结果)

我如何为每位球员获得第n场比赛?

这甚至是查询此问题的正确方法吗?我还有一个玩家桌子,其中一个玩家有很多游戏,一个游戏属于玩家。我应该利用这个吗?

1 个答案:

答案 0 :(得分:2)

要找到特定玩家的第n个最后一个游戏,最好先找到玩家。

player = Player.find_by(name: "user3692508")

然后你可以找到玩家游戏:

player.games

要获得第n个游戏,您可以按games_played降序排序,然后将其限制为一个结果并使用您想要的偏移量抵消:

player.games.order(games_played: :desc).limit(1).offset(0)

如果你做0的偏移,你将获得最后一场比赛。如果你的偏移量为1,你将获得第二场比赛,依此类推。

这假设您的玩家has_many :games和游戏belongs_to :player

通过使用子查询,您可以获得每个玩家的第n个游戏。(看起来像是一团糟......)

offset = 1

sub_query = "SELECT 'sub_game'.id FROM 'games' as sub_game WHERE 'sub_game'.'player_id' = games.player_id ORDER BY 'sub_game'.'games_played' DESC LIMIT 1 OFFSET #{offset}"

Game.joins(:player).where("games.id IN (#{sub_query})").order(id: :desc).group(:player_id)

使用此解决方案,您可以为子查询中的每个玩家排序游戏并首先在那里进行偏移。