从排名中排除零得分的用户

时间:2015-03-06 04:48:06

标签: mysql

我已经遇到过这个很棒的解决方案,可以根据用户在mysql中的得分对用户进行排名。

SELECT  d.*, c.ranks
FROM
        (
          SELECT    Score, @rank:=@rank+1 Ranks
          FROM
                  (
                      SELECT  DISTINCT Score 
                      FROM    tableName a
                      ORDER   BY score DESC
                  ) t, (SELECT @rank:= 0) r
        ) c 
        INNER JOIN tableName d
            ON c.score = d.score

但是,我想知道是否有一种方法可以从排名中排除0或没有得分的用户,但仍会在结果中返回这些用户。

所以例如

KEY     username    password    score   Ranks
1       Anna        123         8       1
2       Bobby       345         5       2
3       Helen       678         5       2
4       Jon         567         -2      3
5       Arthur      ddd         -9      4
4       Chris       444         0       
5       Liz         eee         0       

1 个答案:

答案 0 :(得分:1)

由于您想要选择所有用户,请从以下开始:

SELECT
  user.*
FROM user

现在,我们想要添加一个排名用户的表格,因此我们开始增加复杂性。我们的目标是获得一个排名用户的临时表,因此我们将LEFT JOIN不过滤掉任何未排名的用户。

SELECT
  user.*,
ranked_user.score,
ranked_user.rank
FROM user
LEFT JOIN(
  // subquery
) AS ranked_user ON ranked_user.user_id = user.id

然后我们必须弄清楚确定等级的子查询的部分。你已经拥有了大部分内容,我只是添加一个IF语句,只有在得分时才指定排名。总而言之,你得到了这个:

SELECT
  user.*,
  ranked_user.score,
  ranked_user.rank
FROM user
LEFT JOIN(
  SELECT
    score,
    user_id,
    IF(score = 0 OR score IS NULL, null, @rank:=@rank+1) AS rank
  FROM(
    SELECT
      DISTINCT score,
      user_id
    FROM stat
    ORDER BY score DESC
  ) t, (SELECT @rank:= 0) r
) ranked_user ON ranked_user.user_id = user.user_id

以下是IF语句的工作原理:

IF(score = 0 OR score IS NULL,
# if c.score is 0 or missing

null,
# set the value to null

@rank:=@rank+1) 
# otherwise, calculate a rank

AS rank
# call this value "rank"

只是旁注:我改变了user.*并实际列出了您想要的user的每一列。这被认为是最佳做法。