通过分组进行SQL用户评分排名

时间:2015-08-23 11:40:54

标签: mysql sql mysql-variables

我有以下排名系统。

SET @1=0;

SELECT id, username, magic_xp, @i:=@i+1 AS rank
  FROM hs_users
 ORDER 
    BY magic_xp DESC;

hs_users
id  username     magic_xp rank
988 5hapescape   14926854    1
737 Ozan         13034431    2
989 Kurt         13034431    3
  6 LEGACY              0    4
 11 Bobby               0    5
276 Bobby123            0    6
345 Mynamesjason        0    7
450 Demon Spawn         0    8
987 Satan               0    9

如您所见,我有2个用户拥有相同的xp。

我想让他们都有rank = 2,其余的应该来自​​3

我该如何将它们分组?

|  username  | magic_xp | rank |
| ---------- + -------- + ---- |
| ShapeScape |     1000 |    1 |
| Kurt       |      100 |    2 |
| Ozan       |      100 |    2 |
| Legacy     |       10 |    3 |

4 个答案:

答案 0 :(得分:3)

在MySQL中,最有效的方法是使用变量:

  select t.*,
         (@rank := if(@magic_xp = magic_xp, @rank,
                      if(@magic_xp := magic_xp, @rank + 1, @rank + 1)
                     )
         ) as rank
  from table t cross join
       (select @rank := 0, @magic_xp := NULL) params
  order by magic_xp desc;

注意变量的复杂表达式。两个变量的赋值都在一个表达式中。这是故意的。 MySQL不保证SELECT中表达式的赋值顺序,有时,它甚至不会按顺序对它们进行求值。单个表达式是执行此逻辑的安全方法。

SQL中更标准的方法是使用相关子查询:

select t.*,
       (select count(distinct t2.magic_xp)
        from table t2
        where t2.magic_xp >= t.magic_xp
       ) as rank
from table t;

答案 1 :(得分:0)

<强>查询

set @i := 0;
set @lagxp := null;

select id, username, magic_xp, 
@i := if(@lagxp = magic_xp, @i,
          if(@lagxp := magic_xp, @i + 1, @i + 1)) as rank
from hs_users
order by magic_xp desc
;

SELECT id, username, magic_xp, 
IF (@score=hs_users.magic_xp, @rank:=@rank, @rank:=@rank+1) as rank,
@score:=hs_users.magic_xp score
FROM hs_users, (SELECT @score:=0, @rank:=0) r
ORDER BY magic_xp DESC;

<强>输出

+-----+------------+----------+------+----------+
| id  |  username  | magic_xp | rank |  lagxp   |
+-----+------------+----------+------+----------+
| 988 | Shapescape | 14926894 |    1 | 14926894 |
| 737 | Ozan       | 13034431 |    2 | 13034431 |
| 989 | Kurt       | 13034431 |    2 | 13034431 |
|   6 | Legacy     |        0 |    3 |        0 |
+-----+------------+----------+------+----------+

sqlfiddle

答案 2 :(得分:0)

听取解决方案:)

SELECT id, username, magic_xp, 
IF (@score=hs_users.magic_xp, @rank:=@rank, @rank:=@rank+1) as rank,
@score:=hs_users.magic_xp score
FROM hs_users, (SELECT @score:=0, @rank:=0) r
ORDER BY magic_xp DESC;

感谢@amdixon

答案 3 :(得分:0)

select 
  @rank:=if(magic_xp=@prev_magic_xp,@rank,@rank+1) as rank,
  username,
  magic_xp,
  @prev_magic_xp:=magic_xp as prev_magic_xp

from user,(select @rank:=0,@prev_magic_xp="") t

order by magic_xp desc

供参考:http://sqlfiddle.com/#!9/09bb3/2