2

我必须将排名分配给考试中的 5000 名学生。排名基于分数和获得该分数所花费的时间(以秒为单位)。

例如5个学生的分数相同,则以所取分数作为计算排名的标准,否则以分数作为计算排名的标准。

以下是我的桌子tbRank

ID  StudID  Score Time Date        Rank
1   11      8     60   09-11-2013 
2   22      6     45   09-11-2013
3   33      4     76   09-11-2013
4   44      6     67   09-11-2013
5   55      8     35   09-11-2013 
6   66      8     35   08-11-2013
7   77      8     39   08-11-2013

现在rank column在上表中应更新为:

ID  StudID  Score Time Date        Rank
1   11      8     60   09-11-2013  2
2   22      6     45   09-11-2013  3
3   33      4     76   09-11-2013  5
4   44      6     67   09-11-2013  4
5   55      8     35   09-11-2013  1
6   66      8     35   08-11-2013  1
7   77      8     39   08-11-2013  2

我想做一个 MySQL 查询来做这个生意。同样,表中可以有超过 10000 条记录。所以我需要一个针对这个功能的优化查询。

注意:我使用的是 PHP 和 MYSQL。

Update:每天将在表中创建近 5000 个新条目,并且在完成所有插入后,排名列将每天更新一次。现在请建议我最好的方法来做到这一点。如果我更新表中的排名列,那么我只需要这样做一次,否则每次获取学生的排名时,我都必须进行计算。

4

2 回答 2

2

如果要更新表,可以执行以下操作:

UPDATE tbRank t
INNER JOIN (
  SELECT ID, StudID, Score, `Time`, @rownum := @rownum + 1 AS rank
  FROM (
    SELECT ID, StudID, Score, `Time`
    FROM tbRank
    WHERE date = date(now())
    ORDER BY score DESC, `time` ASC
    ) a
  JOIN (
    SELECT @rownum := 0
    ) r
  ) b ON b.id = t.id
SET t.rank = b.rank

但是由于您每天都会这样做,因此您必须在执行此操作之前将 rank 列的所有行更新为 null。

我不建议使用这种方法,因为如果您更改其中一个或插入新记录,则必须再次进行更新。

每当您想获得排名时,您都可以简单地使用此查询:

SELECT ID, StudID, Score, `Time`, @rownum := @rownum + 1 AS rank
  FROM (
    SELECT ID, StudID, Score, `Time`
    FROM tbRank
    WHERE date = date(now())
    ORDER BY score DESC, `time` ASC
    ) a
  JOIN (
    SELECT @rownum := 0
    ) r

此外,如果您想知道特定学生的排名,可以执行以下查询:

SELECT * FROM 
(
  SELECT ID, StudID, Score, `Time`, @rownum := @rownum + 1 AS rank
  FROM (
    SELECT ID, StudID, Score, `Time`
    FROM tbRank
    WHERE date = date(now())
    ORDER BY score DESC, `time` ASC
    ) a
  JOIN (
    SELECT @rownum := 0
    ) r
  ) b
WHERE b.StudID = 11;

sqlfiddle demo

于 2013-11-09T02:45:01.323 回答
1

所以,这是你的桌子:

ID  StudID  Score Time
1   11      8     60 
2   22      6     45 
3   33      4     76
4   44      6     67
5   55      8     35 

这是构建的查询Rank

SELECT * FROM tbRank GROUP BY Score DESC, Time ASC

它会“重新排列”你的表格中得分最高的行,最快的时间将从上到下排列

于 2013-11-09T02:42:53.147 回答