【问题标题】:How to distribute ranking using MySQL Query and PHP如何使用 MySQL Query 和 PHP 分配排名
【发布时间】:2013-11-21 05:02:39
【问题描述】:

我必须将排名分配给参加考试的 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 个新条目,并且在完成所有插入后,排名列将每天更新一次。现在请建议我最好的方法来做到这一点。如果我更新表中的排名列,那么我只需要这样做一次,否则每次获取学生的排名时,我都必须进行计算。

【问题讨论】:

  • 嗯,我很抱歉。我已经在我的mysql中尝试过了。所以我有解决方案。
  • 你在这里包含了 php,所以问题是排名列将是你表中的附加列还是只是 php 中的显示?
  • @DrixsonOseña - 老实说,我不知道该怎么做?我是在表格中保留一列还是只是计算它的运行时间以显示在网页上?我需要建议。
  • @nkp 正如我在回答中提到的那样,使用排名列的缺点是,每当您输入新记录或修改现有记录时,您都必须再次进行更新,因为您必须重新计算才能使表格准确。如果您删除该列并仅从我的第二个查询中进行排名,您不必担心该表,并且每当您需要获得排名时,您只需为其进行选择。
  • @FilipeSilva - 我对您的第二个问题感到满意。但在我的要求中,表格每天只更新一次。我忘了在我的表中提及日期字段。我也必须考虑日期的查询,即更新今天日期的排名。我正在更新我的问题。

标签: php mysql sql


【解决方案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

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

【讨论】:

  • 这将根据我的需要对我的表进行排序。排名栏呢?我必须给每个学生排名。
  • 如果需要,Rank 列必须是 alias。请参阅@Filipe Silva 的回答。我认为这对你来说是一个正确的解决方案
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多