如果我们的排名取决于两栏,让我们说得分和时间, 我希望得分最高,时间最短。
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
答案 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