1

I'm familiar with Oracle and would normally do a RANK() (ORDER BY score DESC) AS rank to get a rank like this:

 Score | Rank
--------------
   100 |    1
   100 |    1
    99 |    3
    98 |    4
    98 |    4
    98 |    4
    97 |    7

I haven't got the foggiest how to do this in MySQL - after looking on here, I've found this:

SET @prev_value = NULL;
SET @rank_count = 0;
SELECT score
     , CASE
       WHEN @prev_value = score 
          THEN @rank_count
       WHEN @prev_value := score 
          THEN @rank_count := @rank_count + 1
       END AS rank
  FROM ...

but this returns it as:

 Score | Rank
--------------
   100 |    1
   100 |    1
    99 |    2
    98 |    3
    98 |    4
    98 |    4
    97 |    5

Which isn't quite what I wanted.

Alex K
  • 8,269
  • 9
  • 39
  • 57
ash
  • 1,224
  • 3
  • 26
  • 46

2 Answers2

2

Add another variable:

SET @prev_value = NULL;
SET @rank_count = 0;
SET @rank_increasing = 0;
SELECT score
     , @rank_increasing := @rank__increasing + 1 AS row_num
     , CASE
       WHEN @prev_value = score 
          THEN @rank_count
       WHEN @prev_value := score 
          THEN @rank_count := @rank_increasing
       END AS rank
  FROM ...
Barmar
  • 741,623
  • 53
  • 500
  • 612
1
SELECT score
     , FIND_IN_SET(score,(SELECT GROUP_CONCAT(score ORDER BY score DESC) FROM my_scores))
  FROM my_scores;

or, if you want to get closer to the speed of Barmar's query...

SELECT score
     , FIND_IN_SET(score, @vals) rank
  FROM my_scores
  JOIN (SELECT @vals := GROUP_CONCAT(score ORDER BY score DESC) FROM my_scores) x;

Of course GROUP_CONCAT has certain limitations!

Strawberry
  • 33,750
  • 13
  • 40
  • 57
  • Thank you for this answer Strawberry - Barmar's query, I think, is best for me as 'my_scores' is an inline view. – ash Jul 25 '14 at 10:50