Question

I have a simple extension of the greatest-n-per-group problem.

Here is my query:

$q = 
'SELECT            
    played.words, MAX(played.score) max_score, played.longest, played.game_options, 
    users.first_name 
FROM played 
INNER JOIN users
ON played.user_id = users.user_id       
GROUP BY game_options 
';

Unfortunately, while I always get the maximum score for a given game_options, the user.first_name is usually wrong (e.g. for the same game_options value, Tom played first and got a 63, while Joe played second and got a 100; instead of Joe, Tom is returned with Joe's high score).

I assume I need to do some sort of inner join, but could not figure it out since I already have an inner join that relates two tables (a users table and a games played table). I have to imagine this is a duplicate question but could not find it. Thanks for any help.

Was it helpful?

Solution

One way to show all tied results:

SELECT            
    p.words, 
    p.score AS max_score, 
    p.longest, 
    p.game_options, 
    u.first_name, 
    m.cnt AS game_played_count
FROM played AS p
  INNER JOIN users AS u
    ON  p.user_id = u.user_id
  INNER JOIN 
    ( SELECT 
          pp.game_options, 
          MAX(pp.score) AS score,
          COUNT(*) AS cnt
      FROM played AS pp      
      GROUP BY pp.game_options 
    ) AS m
    ON  m.game_options = p.game_options
    AND m.score = p.score ;

With ties resolved according to a predefined order:

SELECT            
    p.words, 
    p.score AS max_score, 
    p.longest, 
    p.game_options, 
    u.first_name,
    dp.cnt AS game_played_count
FROM 
    ( SELECT game_options,
             COUNT(*) AS cnt
      FROM played
      GROUP BY game_options
    ) AS dp
  INNER JOIN played AS p
    ON  p.play_id =                         -- assuming that `play_id` is the PK
    ( SELECT pi.play_id
      FROM played AS pi
      WHERE pi.game_options = dp.game_options   
      ORDER BY pi.score DESC,               -- the predefined
               pi.play_id ASC               -- order
      LIMIT 1 
    ) 
  INNER JOIN users AS u
    ON  p.user_id = u.user_id ;

An index on (game_options, score, play_id) would help efficiency - in both queries.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top