Mysql 排名靠前

Mysql 排名靠前,mysql,database,ranking,Mysql,Database,Ranking,我是sql新手,我从未在mysql中使用过变量或条件,但从其他编程语言中知道这一点。几天以来,我一直试图找到一种方法来给用户评分。我读了很多关于stackoverflow的文章,也问了很多问题,最后我找到了一个几乎能满足我需求的解决方案 SELECT score_users.uid, score_users.score, @prev := @curr, @curr := score, @rank := IF(@prev = @curr, @rank, @rank +1) AS

我是sql新手,我从未在mysql中使用过变量或条件,但从其他编程语言中知道这一点。几天以来,我一直试图找到一种方法来给用户评分。我读了很多关于stackoverflow的文章,也问了很多问题,最后我找到了一个几乎能满足我需求的解决方案

SELECT
  score_users.uid,
  score_users.score,
  @prev := @curr,
  @curr := score,
  @rank := IF(@prev = @curr, @rank, @rank +1) AS rank
FROM
  score_users,
  (SELECT @curr := null, @prev := null, @rank := 0) tmp_tbl
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC
但我的问题是平局。我不想得到连续的排名,就像这样:

+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   3  |  18   |
| 7   | Mary  |   4  |  17   |
| 3   | Toni  |   5  |  12   |
| 5   | Steve |   5  |  12   |
| 6   | Peter |   6  |  11   |
| 8   | Nina  |   7  |  10   |
+------------+------+--------+
+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   4  |  18   |
| 7   | Mary  |   5  |  17   |
| 3   | Toni  |   6  |  12   |
| 5   | Steve |   6  |  12   |
| 6   | Peter |   8  |  11   |
| 8   | Nina  |   9  |  10   |
+------------+------+--------+
SELECT
  score_users.uid,
  score_users.score,
  @prev := @curr,
  @curr := score,
  @rank := IF(@prev = @curr, @rank, @rank + @i) AS rank,
  IF(@prev <> score, @i:=1, @i:=@i+1) AS counter
FROM
  score_users,
  (SELECT @curr := null, @prev := null, @rank := 0, @i := 0) tmp_tbl
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC
我希望得到这样的结果:

+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   3  |  18   |
| 7   | Mary  |   4  |  17   |
| 3   | Toni  |   5  |  12   |
| 5   | Steve |   5  |  12   |
| 6   | Peter |   6  |  11   |
| 8   | Nina  |   7  |  10   |
+------------+------+--------+
+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   4  |  18   |
| 7   | Mary  |   5  |  17   |
| 3   | Toni  |   6  |  12   |
| 5   | Steve |   6  |  12   |
| 6   | Peter |   8  |  11   |
| 8   | Nina  |   9  |  10   |
+------------+------+--------+
SELECT
  score_users.uid,
  score_users.score,
  @prev := @curr,
  @curr := score,
  @rank := IF(@prev = @curr, @rank, @rank + @i) AS rank,
  IF(@prev <> score, @i:=1, @i:=@i+1) AS counter
FROM
  score_users,
  (SELECT @curr := null, @prev := null, @rank := 0, @i := 0) tmp_tbl
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC
我想我必须创建一个新的临时表,如果有条件的话,我也会创建一些,但我找不到解决方案,变得绝望!
另外,我必须关注表现,也许有更好的方法让我在得分上排名?我将非常感谢您的提示或一些代码片段。

您可以使用另一个变量来计算相同的秩,因此,您不必将@rank增加1,而是将@rank增加计数器值,如下所示:

+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   3  |  18   |
| 7   | Mary  |   4  |  17   |
| 3   | Toni  |   5  |  12   |
| 5   | Steve |   5  |  12   |
| 6   | Peter |   6  |  11   |
| 8   | Nina  |   7  |  10   |
+------------+------+--------+
+------------+------+--------+
| uid | name  | rank | score |
+------------+------+--------+
| 4   | Jon   |   1  |  20   |
| 1   | Jane  |   2  |  19   |
| 2   | Fred  |   2  |  19   |
| 9   | July  |   4  |  18   |
| 7   | Mary  |   5  |  17   |
| 3   | Toni  |   6  |  12   |
| 5   | Steve |   6  |  12   |
| 6   | Peter |   8  |  11   |
| 8   | Nina  |   9  |  10   |
+------------+------+--------+
SELECT
  score_users.uid,
  score_users.score,
  @prev := @curr,
  @curr := score,
  @rank := IF(@prev = @curr, @rank, @rank + @i) AS rank,
  IF(@prev <> score, @i:=1, @i:=@i+1) AS counter
FROM
  score_users,
  (SELECT @curr := null, @prev := null, @rank := 0, @i := 0) tmp_tbl
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC

添加另一个始终递增的秩字段。如果值匹配,则使用未递增的现有秩,否则使用始终递增的秩

SELECT
  score_users.uid,
  score_users.score,
  @prev := @curr,
  @curr := score,
  @rank1 := @rank1 + 1,
  @rank := IF(@prev = @curr, @rank, @rank1) AS rank 
FROM
  score_users,
  (SELECT @curr := null, @prev := null, @rank := 0, @rank1 := 0) tmp_tbl
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC

在平局中,您可能希望跳过并使用当前行num到下一个不匹配的得分值行作为下一个排名。 以下内容应该对您有所帮助

SELECT
    score_users.uid
  , @curr_score := score_users.score as score,
  , case when @prev_score = @curr_score then @rank := @rank 
         else @rank := ( @curr_row + 1 ) -- <- this is what you require
     end as rank
  , @curr_row := ( @curr_row + 1 ) as curr_row
  , @prev_score := @curr_score
FROM
  score_users,
  ( SELECT @curr_score := 0, @prev_score := 0
         , @curr_row := 0,   @rank := 0 ) initializer
WHERE
  score_users.matchday = 1
ORDER BY
  score_users.score DESC

我会在SQL之外生成排名,因为无论您使用什么程序,只要按分数排名就足够了。在MySQL中,做你正在做的事情是很复杂的!谢谢,阿齐兹,这个很好用。我只是在子选择中将@rank设置为1,否则排名以0开始!干杯我也在做类似的事情,但我在第二场平局前加了一个“T”——2,T2。适用于@prev_val:=分数,然后concat'T',@count-1-但如果有3个平局值,则不执行2,T2,T2-获得2,T2,T3。有什么办法可以做到这一点吗?