Reputation: 199
I have a table named Game which is filled with individual players statlines from all their games in an nhl season. The fields That I am concerned with here are games_played which = n for the nth game of a player in the season. and name which is the players name.
Essentially I am trying to figure out how to grab the nth last game for each player.
For instance I know the following query can get me the last game for each player
Game.group(:name).having('games_played = MAX(games_played)')
However when I try the following (lets say n is 10)
Game.group(:name).having('games_played=MAX(games_played)-10')
I get no results
and in fact if I explicitly do something like
Game.group(:name).having('games_played=16')
I only get the last game of players who played exactly 16 games, instead of the 16th game for all players. (Which I guess explains the no results of the previous query)
How do I go about getting the nth last game for each player?
Is this even the right way to query this? I also have a player table where a player has_many games, and a game belongs_to a player. Should I be taking advantage of that?
Upvotes: 3
Views: 1285
Reputation: 1517
To find the nth last game for a specific player, it would probably be easiest to start by finding the player.
player = Player.find_by(name: "user3692508")
then you can find the players games with:
player.games
To get the nth last game, you can order it by games_played
in descending order, then limit it to one result and offset it with the offset you want:
player.games.order(games_played: :desc).limit(1).offset(0)
If you do an offset of 0, you will get the last game. If you do an offset of 1 you will get the 2nd last game and so on.
This is assuming your player has_many :games
and the game belongs_to :player
By using a sub query you can get the nth last game for each player.(it looks like a mess.....)
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)
With this solution, you would sort the games for each player in the sub query and do the offset there first.
Upvotes: 2