0

我正在做一个需要硬编码排名的项目(请不要规范化评论)。该示例有一个分数表。每条得分记录都与一个人和一个特定的游戏迭代有关。我们只想对一个人在游戏的特定迭代中的最高得分进行排名,因为一个人可能在某个时候打破自己的得分并拥有多个记录。以下查询用于标记每个人在特定游戏迭代中的最高得分,以便可以单独对其进行排名。

以下是非常慢的,我想加快速度:

/* Define a game iteration */
SET @VarID=(can be any number from 1-200k);

/* WITHIN A game iteration RESET ALL OF THE PERSONAL BEST */

UPDATE scores m
SET m.personal_best='0'
WHERE VarID = @VarID;

/* IDENTIFY THE "BEST" (in this case the highest score per PeopleID) */

UPDATE scores m
SET m.personal_best='1'
WHERE m.ScoreID IN 
(
    SELECT _scoreID
    FROM
    (   
        SELECT ScoreID as _scoreID FROM scores WHERE VarID = @VarID AND NewScore = ( select max(NewScore) from scores i where i.PeopleID = scores.PeopleID AND VarID = @VarID ) ORDER BY VarID, NewScore DESC   
    ) s

) AND VarID = @VarID;
4

1 回答 1

0

您可以使用 MySQL 的多表 UPDATE 语法在没有子查询的情况下执行此操作。

使用 OUTER JOIN,查找同一个人和变量的分数,以及更高的分数。如果没有找到更高的分数(即如果m是分数最高的行),那么外连接将使连接表的所有列都为 NULL。

UPDATE scores m
LEFT OUTER JOIN scores AS better
  ON m.VarID = better.VarID AND m.PeopleID = better.PeopleID 
  AND m.NewScore < better.NewScore
SET m.personal_best='1'
WHERE VarID = @VarID
  AND better.VarID IS NULL;

但可能有联系;如果此人不止一次达到他们的最佳分数,则会将不止一行标记为他们的最佳分数。如果你想避免这种情况,你必须使用其他一些保证唯一的列来打破关系:

UPDATE scores m
LEFT OUTER JOIN scores AS better
  ON m.VarID = better.VarID AND m.PeopleID = better.PeopleID 
  AND (m.NewScore < better.NewScore OR m.NewScore = better.NewScore AND m.ScoreID < better.ScoreID)
SET m.personal_best='1'
WHERE VarID = @VarID
  AND better.VarID IS NULL;
于 2013-07-02T18:43:00.010 回答