I am not sure if this question has been asked yet but I don't know how to word it better :)
I have a table with game results. I need to return the top 10 results (for a leaderboard) but my results has to return the highest game per player and not replicate the player (so I am looking for each players highest score and based on that the top 10 players, not say if I am 1st and 3rd on scores to show me twice).
The SQL I am using at the moment is:
SELECT
`games`.`score`,
CONCAT(`users`.`full_name`) AS `name`,
`users`.`facebook_id`
FROM
`games`,
`users`
WHERE
`games`.`user_id`=`users`.`id`
AND `users`.`id` IN ('user ids goes here')
AND `games`.`status`=2
ORDER BY
`games`.`score` DESC
LIMIT 10";
Can this be done with a single query or would it be best to work on the returned array and create my desired results from there?
UPDATE:
To best illustrate, say we have the following results:
Jack - 300 points
Jill - 280 points
Gareth - 250 points
Jack - 240 points (this is the same jack)
Peter - 230 points
....
I want to return from all of the games the top 10 players based on their highest score, so not neccesarily 10 results, but I'm looking for a result which would then return the following:
Jack - 300 points
Jill - 280 points
Gareth - 250 points
Peter - 230 points
So The 2nd Jack is removed because he is already on the list just with a higher score.
I hope this helps :)
Okay, let's do this step by step.
With this query, we get a list of games and their players, sorted by game and score. We add a rownumber which resets to 1 for each game.
SELECT
games.game_id,
`games`.`score`,
CONCAT(`users`.`full_name`) AS `name`,
`users`.`facebook_id`,
@row_num := if(@game != games.game_id, 1, @row_num + 1) AS rownumber,
@game := games.game_id
FROM
`games`
INNER JOIN users ON `games`.`user_id`=`users`.`id`
, (select @row_num := 1, @game := NULL) variables
WHERE
`users`.`id` IN ('user ids goes here')
AND `games`.`status`=2
ORDER BY
games.game_id, /*or something*/
`games`.`score` DESC
Now we can get the top 10 players for each game by putting above query into this
SELECT * FROM (
<above query here>
) subquery_alias
WHERE rownumber <= 10;
Now we just have to add a GROUP BY playername and get the greatest result. So your final query is this:
SELECT name, MAX(score) FROM (
SELECT
games.game_id,
`games`.`score`,
CONCAT(`users`.`full_name`) AS `name`,
`users`.`facebook_id`,
@row_num := if(@game != games.game_id, 1, @row_num + 1) AS rownumber,
@game := games.game_id
FROM
`games`
INNER JOIN users ON `games`.`user_id`=`users`.`id`
, (select @row_num := 1, @game := NULL) variables
WHERE
`users`.`id` IN ('user ids goes here')
AND `games`.`status`=2
ORDER BY
games.game_id, /*or something*/
`games`.`score` DESC
) subquery_alias
WHERE rownumber <= 10
GROUP BY `name`