我已经遇到过这个很棒的解决方案,可以根据用户在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
答案 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
的每一列。这被认为是最佳做法。