如何在mysql表中显示RANK?

时间:2017-02-09 12:40:43

标签: mysql sql database

如果我们的排名取决于两栏,让我们说得分和时间, 我希望得分最高,时间最短。

CREATE TABLE yourTable (id int, userid int, questions int, `date` varchar(10),
                        rightquestions int, examid int, `time` int);
INSERT INTO yourTable (id, userid, questions, `date`, rightquestions, examid, `time`)
VALUES
    (1, 10, 5, '02/09/2017', 5, 2, 11),
    (2, 12, 5, '02/09/2017', 5, 2, 11),
    (9, 16, 5, '02/09/2017', 4, 2, 18),
    (8, 15, 5, '02/09/2017', 3, 2, 18);

如上所示,在我的表中得分= rightanswers和时间=时间

现在,如果我想按最高权利和最低时间排名,那么查询应该是什么?

我尝试了这个,但得到了意想不到的结果

SELECT id, rightquestions, leagueid,time,
CASE 
WHEN @prevRank = rightquestions AND @prevTime != time THEN @curRank  
WHEN @prevRank != rightquestions AND @prevTime != time THEN @curRank 
WHEN @prevRank := rightquestions AND @prevTime := time AND @curRank = 0 THEN @curRank := @curRank + 1
END AS rank
FROM results p,
(SELECT @curRank :=0, @prevRank := NULL, @prevTime := NULL) r
ORDER BY rightquestions DESC,time ASC

2 个答案:

答案 0 :(得分:0)

您可以使用行号会话变量以及用于标识唯一rightquestions / time对的子查询来模拟MySQL中的密集排名。请尝试以下查询,该查询基于您与我们共享的表快照:

SET @row_number = 0;

SELECT t1.rightquestions, t1.`time`, t2.rank
FROM yourTable t1
INNER JOIN
(
    SELECT (@row_number:=@row_number + 1) AS rank, t.rightquestions, t.`time`
    FROM
    (
        SELECT rightquestions, `time`
        FROM yourTable
        GROUP BY rightquestions, `time`
    ) t
    ORDER BY t.rightquestions DESC, t.`time`
) t2
    ON t1.rightquestions = t2.rightquestions AND
       t1.`time`  = t2.`time`

以下是我在本地测试时在Workbench中获得的输出:

rightquestions | time | rank
5              | 11   | 1
5              | 11   | 1
4              | 18   | 2
3              | 18   | 3

答案 1 :(得分:0)

您需要一个会话变量,该变量将在每次分数更改时增加并重新启动。您还可以在实际查询中的“假”连接中对其进行初始化,如下所示:

select timer, if(@score = score,@rank:=@rank+1,@rank:= 1) as rank ,@score:=score as score
from (
      select 1 score, now() + interval rand()*10 hour as timer
      union all
      select 1 score, now() + interval rand()*10 hour as timer
      union all
      select 2 score, now() + interval rand()*10 hour as timer
      union all
      select 3 score, now() + interval rand()*10 hour as timer
      union all
      select 3 score, now() + interval rand()*10 hour as timer
)
 t
 join (select @rank:=0, @score := 0)r on (1=1) 
 order by score, timer asc