views:

117

answers:

6

I have an application that tracks high scores in a game.

I have a user_scores table that maps a user_id to a score.

I need to return the 5 highest scores, but only 1 high score for any specific user.

So if user X has the 5 highest scores on a purely numerical basis, I simply return the highest one and then the next 4 user scores.

I have tried to use:

SELECT user_id, score 
FROM user_scores 
ORDER BY score DESC 
GROUP BY user_id 
LIMIT 5

But it seems that MySQL drops any user_id with more than 1 score.

A: 

You can't group by without a summary-function (SUM, COUNT, etc.)

The GROUP BY clause says how to group the SUMs or COUNTs.

If you simply want to break the long list into bunches with a common value, that's not SQL. That's what your application has to do.

S.Lott
You can in MySQL. As the original poster found, MySQL just grabs a random possible value for the column that is not grouped.I think that this is a very dangerous misfeature with lots of potential for accidentally saying what you really didn't mean.
Yup. That's a non-standard "feature" that amounts to a bug.
S.Lott
A: 

Can you use the Distinct operator to say

SELECT DISTINCT(user_id), score
FROM user_scores
ORDER BY score DESC
LIMIT 5

didn't test so not sure if that will definitely work

JustinD
+5  A: 

This should work:

SELECT user_id, MAX(score)
FROM user_scores 
GROUP BY user_id 
ORDER BY MAX(score) DESC 
LIMIT 5
Alexander Kojevnikov
beaten by 27 seconds!
Swati
I think it should actually be "ORDER BY score DESC" - but thanks, got it working a treat.
Toby Hede
I don't have mysql at hand, but AFAIR you cannot ORDER BY a non-aggregated column.
Alexander Kojevnikov
A: 

Returning only the maximum score for a given user is something like the following.

SELECT user_id, max(score) FROM user_scores
GROUP BY user_id
S.Lott
+1  A: 
SELECT user_id, MAX(score) AS score
FROM user_scores 
GROUP BY user_id
ORDER BY score DESC
LIMIT 5

Should do the job for you... though don't forget to create indexes...

Mez
A: 

I don't know whether it was a lack of caffeine or just brain explosion, but the answers here were so easy.

I actually got it working with this monstrosity:

SELECT s1.user_id, 
    (SELECT score FROM user_scores s2 WHERE s2.user_id = s1.user_id ORDER BY score DESC LIMIT 1) AS score 
FROM user_scores s1         
GROUP BY s1.user_id
ORDER BY s1.score DESC     
LIMIT 5
Toby Hede
That is a monstrosity!
Mez