tags:

views:

85

answers:

2

I have a table which stores test results like this:

user | score | time
-----+-------+------
aaa  | 90%   | 10:30
bbb  | 50%   | 9:15   ***
aaa  | 85%   | 10:15
aaa  | 90%   | 11:00  ***
...

What I need is to get the top 10 users:

user | score | time
-----+-------+------
aaa  | 90%   | 11:00
bbb  | 50%   | 9:15
...

I've come up with the following SELECT:

SELECT * FROM (SELECT user, score, time
               FROM tests_score
               ORDER BY user, score DESC, time DESC) t1
GROUP BY user
ORDER BY score DESC, time
LIMIT 10

It works fine but I'm not quite sure if my use of ORDER BY is the right way to pick the first row of each group of sorted records. Is there any better practice to achieve the same result? (I use MySQL 5)

+1  A: 

another solution to be sure to get the max score could be

SELECT t1.* 
  FROM tests_score t1
  JOIN (SELECT user, MAX(score)  
          FROM test_score  
      GROUP BY user) as t2 ON t1.user = t2.user  
                          AND t1.score = t2.score
PierrOz
Thanks for your suggestion though, this version doesn't deal with duplicate user/score pairs. It also doesn't take into account time corresponding to the row.
FipS
A: 

It seems like you want the score with the latest time.

This query gets the most current score for each user and orders them by score.

SELECT user, MAX(score), time
FROM test_results tr
LEFT OUTER JOIN test_results tr2
ON tr2.user = tr.user AND tr2.time > tr.time
WHERE tr2.user IS NULL
GROUP BY user
ORDER BY MAX(score) DESC, time

If two scores are posted for the same time for the same user, the larger one is used. This only works if the score is an integer column, not a string column, since 5% comes before 60% alphabetically.

Marcus Adams
Thanks, after a little tweaking, your query returns exactly the same result as my original one. As I'm interested in top scores rather than in recent ones, I substituted 'tr2.time > tr.time' for '(tr2.score > tr.score OR (tr2.score = tr.score AND tr2.time > tr.time))', which I believe makes sense. Thanks again for your help, my knowledge of SQL is very limited and I believe that your version is much cleaner than mine.
FipS