内部联接已存在的最大n组

时间:2014-01-04 11:51:49

标签: mysql greatest-n-per-group

我对每组最大的问题进行了简单的扩展。

这是我的问题:

$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 
';

不幸的是,虽然我总是获得给定game_options的最高分,但user.first_name通常是错误的(例如,对于相同的game_options值,Tom先打得63,而Joe打第二,得到100;相反乔,汤姆以乔的高分回归。

我假设我需要进行某种内部联接,但由于我已经有一个与两个表相关联的内部联接(用户表和游戏表),因此无法解决这个问题。我不得不想象这是一个重复的问题,但找不到它。谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

显示所有相关结果的一种方法:

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 ;

根据预定义的顺序解决关系:

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 ;

(game_options, score, play_id)上的索引有助于提高效率。