Помогите сделать правильный запрос

Имеем: таблица с полями id(ключ-добавляется автоматом) id_game(идентификатор игры), id_user(идентификатор пользователя), score(очки пользователя).
В таблице могуть быть множество записей для оного и того же пользователя и так же для отдной и той же игры.

Как выбрать из таблицы по идентификаторам игр и пользователей только пять пользователей с максимальным количеством очков???
Пользователи в этой пятерке лидеров повторятся не должны И так же не должны повторятся идентификаторы игр.
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }
SELECT id_user, MAX(score)  FROM....
GROUP BY id_user ORDER BY  MAX(score) DESC LIMIT  5
 

Думал эксперементировать и в GROUP добавить еще один столбец id_game, но в результате получается, что образуются группы по id_game, а в них погруппы по id_user и если один и тот же пользователь ведет счет в разных группа он будет повторятся в общем результате запроса, а надо, что бы не повторялся!
Пробовал с подзапросом
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .mysql.geshi_code {font-family:monospace;} .mysql.geshi_code .imp {font-weight: bold; color: red;} .mysql.geshi_code .kw1 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw2 {color: #990099; font-weight: bold;} .mysql.geshi_code .kw3 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw4 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw5 {color: #999900; font-weight: bold;} .mysql.geshi_code .kw6 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw7 {color: #FF9900; font-weight: bold;} .mysql.geshi_code .kw8 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw9 {color: #9900FF; font-weight: bold;} .mysql.geshi_code .kw10 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw11 {color: #CC0099; font-weight: bold;} .mysql.geshi_code .kw12 {color: #009900;} .mysql.geshi_code .kw13 {color: #000099;} .mysql.geshi_code .kw14 {color: #000099;} .mysql.geshi_code .kw15 {color: #000099;} .mysql.geshi_code .kw16 {color: #000099;} .mysql.geshi_code .kw17 {color: #000099;} .mysql.geshi_code .kw18 {color: #000099;} .mysql.geshi_code .kw19 {color: #000099;} .mysql.geshi_code .kw20 {color: #000099;} .mysql.geshi_code .kw21 {color: #000099;} .mysql.geshi_code .kw22 {color: #000099;} .mysql.geshi_code .kw23 {color: #000099;} .mysql.geshi_code .kw24 {color: #000099;} .mysql.geshi_code .kw25 {color: #000099;} .mysql.geshi_code .kw26 {color: #000099;} .mysql.geshi_code .kw27 {color: #00CC00;} .mysql.geshi_code .coMULTI {color: #808000; font-style: italic;} .mysql.geshi_code .co1 {color: #808080; font-style: italic;} .mysql.geshi_code .co2 {color: #808080; font-style: italic;} .mysql.geshi_code .es0 {color: #004000; font-weight: bold;} .mysql.geshi_code .es1 {color: #008080; font-weight: bold;} .mysql.geshi_code .br0 {color: #FF00FF;} .mysql.geshi_code .sy1 {color: #CC0099;} .mysql.geshi_code .sy2 {color: #000033;} .mysql.geshi_code .st0 {color: #008000;} .mysql.geshi_code .nu0 {color: #008080;} .mysql.geshi_code span.xtra { display:block; }

     SELECT id_user, MAX(score)  FROM....
     WHERE id_game IN (
                 SELECT id FROM....
                 WHERE - и как в этом подзапросе
                               мне выбрать id тех строк
                               в которых MAX(score) ???????
                 GROUP BY id_game
     )                      
     GROUP BY id_user ORDER BY  MAX(score) DESC LIMIT  5
 

Спасибо.

1 ответов


DISTINCT для одного столбца быть не может, потому что в этом случае непонятно что должно быть в других столбцах этой же строки. Ваш вопрос слишком хитер для реляционной базы. Для практического применения лучшим вариантом было бы взять первоначальный запрос с группировкой по игроку и игре, увеличить лимит до 20 или больше (чтоб точно влезли все строки с учетом дублей),


SELECT id_user, id_game, MAX(score) as score
FROM....
GROUP BY id_user, id_game
ORDER BY score DESC LIMIT  20;
 

затем повторяющихся игроков и игры удалить в php (или на чем вы пишите). При составлении результата проверять, не было ли такой игры или игрока в предыдущих строчках результата и если была, пропускать строчку.

Проблема с MySQL в том, что вы не можете посмотреть, какие поля были в предыдущей строке. Это решается через заведение переменных типа

@rank := IF(@prev_game != game_id and @prev_user != user_id, 1, 0) AS rank
 
но в данном случае смотреть надо не на одну предыдущую строчку, а как минимум на четыре.
Попробую завтра еще подумать.

Не знаю mysql, но может это поможет - код на mssql, возвращает 3 а не 5 записей только потому, что мне было лень ручками заполнять их дальше :) :


;WITH Score AS
(
  SELECT 1 AS UserID, 1 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 1 AS UserID, 2 AS GameID, 10 AS ScorePoints
  UNION ALL  
  SELECT 1 AS UserID, 3 AS GameID, 1000 AS ScorePoints
  UNION ALL  
  SELECT 2 AS UserID, 1 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 2 AS UserID, 3 AS GameID, 10 AS ScorePoints
  UNION ALL  
  SELECT 3 AS UserID, 2 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 3 AS UserID, 3 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 3 AS UserID, 1 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 3 AS UserID, 4 AS GameID, 100 AS ScorePoints
  UNION ALL  
  SELECT 4 AS UserID, 1 AS GameID, 1555500 AS ScorePoints
  UNION ALL  
  SELECT 4 AS UserID, 4 AS GameID, 10550 AS ScorePoints
  UNION ALL  
  SELECT 5 AS UserID, 3 AS GameID, 5000 AS ScorePoints
  UNION ALL  
  SELECT 6 AS UserID, 1 AS GameID, 10000 AS ScorePoints
  UNION ALL  
  SELECT 7 AS UserID, 1 AS GameID, 10000 AS ScorePoints
)

-- with T-SQL specific functions --------------------------------------
SELECT TOP(5) s.UserID, s.GameID, s.ScorePoints
FROM
(
  SELECT UserID, GameID, ScorePoints,
    ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY ScorePoints DESC) AS RowNumUser,
    ROW_NUMBER() OVER (PARTITION BY GameID ORDER BY ScorePoints DESC) AS RowNumGame
  FROM Score
) AS s
WHERE s.RowNumUser = 1 AND s.RowNumGame = 1
ORDER BY s.ScorePoints DESC
--------------------------------------------------------------------------------------

-- without T-SQL specific functions ---------------------------------------------
SELECT TOP(5) u.UserID, g.GameID, u.ScorePoints
FROM
(
  SELECT a.UserID, b.GameID, a.ScorePoints
  FROM
  (
    SELECT s.UserID, MAX(s.ScorePoints) AS ScorePoints
    FROM Score AS s
    GROUP BY s.UserID
  ) AS a
  INNER JOIN Score AS b
    ON a.UserID = b.UserID AND a.ScorePoints = b.ScorePoints
) AS u
INNER JOIN
(
  SELECT b.UserID, a.GameID, a.ScorePoints
  FROM
  (
    SELECT s.GameID, MAX(s.ScorePoints) AS ScorePoints
    FROM Score AS s
    GROUP BY s.GameID
  ) AS a
  INNER JOIN Score AS b
    ON a.GameID = b.GameID AND a.ScorePoints = b.ScorePoints
) AS g
  ON u.UserID = g.UserID AND u.GameID = g.GameID
ORDER BY u.ScorePoints DESC
-------------------------------------------------------------------------------------------
 


SELECT s1.ID, s1.UserID, s1.GameID, s1.ScorePoints FROM Scores s1
WHERE NOT EXISTS (SELECT s2.ID FROM Scores s2
                      WHERE s1.ID <> s2.ID AND (s2.UserID = s1.UserID OR s2.GameID = s1.GameID) AND s2.ScorePoints > s1.ScorePoints)
ORDER BY 4 DESC LIMIT 5