-1

I want to rank the total stats of a group of users and assign a rank variable to them. I used this thread for the Rank variable.

This is my Query atm:

SELECT @rank := @rank + 1 AS rank
     , SUM(stats.points) AS x 
  FROM 
     ( SELECT @rank := 0 ) r
     , groups 
  LEFT 
  JOIN user_group 
    ON groups.id = user_groups.clan 
  LEFT 
  JOIN stats 
    ON user_groups.user = stats.id 
 GROUP  
    BY groups.id 
 ORDER 
    BY x DESC

RANK | points 
--------------
  47 |    3400     
  1  |    2500     
  75 |    1200     

As you can see the Sorting by Points works fine, but the Rank variable seems to just pick random values. Can anyone find a way to assign the rank correctly?

Strawberry
  • 33,750
  • 13
  • 40
  • 57
Electro
  • 5
  • 2

1 Answers1

0

Use a subquery for the aggregation and ordering:

SELECT id, sum_points, @rank := @rank + 1 AS rank
FROM (SELECT g.id, SUM(s.points) AS sum_points
      FROM groups g LEFT JOIN
           user_group ug
           ON g.id = ug.clan LEFT JOIN
           stats s
           ON ug.user = s.id
      GROUP BY g.id
      ORDER BY sum_points DESC
     ) s CROSS JOIN
     (SELECT @rank := 0) params;

This has been an issue in MySQL for a while -- variables don't work well with aggregation and ordering.

Note that in MySQL 8+, this is much more simply written as:

SELECT g.id, SUM(s.points) AS sum_points,
       ROW_NUMBER() OVER (ORDER BY SUM(s.points) DESC) as rank
FROM groups g LEFT JOIN
     user_group ug
     ON g.id = ug.clan LEFT JOIN
     stats s
     ON ug.user = s.id
GROUP BY g.id
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786