我正在开发一个需要硬编码排名的项目(请不要进行标准化评论)。该示例有一个分数表。每个得分记录涉及一个人和游戏的特定迭代。我们只想对一个人对游戏的特定迭代的最高分进行排名,因为一个人可以在某个时刻打破他们自己的分数并拥有多个记录。以下查询用于标记特定游戏迭代的每个人的最高分数,以便可以单独排名。
以下是非常缓慢的,我想加快速度:
/* 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;
答案 0 :(得分:0)
您可以使用MySQL的多表UPDATE语法在没有子查询的情况下执行此操作。
使用OUTER JOIN,查找同一个人和varid的分数,以及更高的分数。如果未找到更高的分数(即,如果 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;