2013-07-02 97 views
0

我正在研究需要硬編碼排名的項目(請勿標準化評論)。這個例子有一個分數表。每個得分記錄都與一個人和一個特定的遊戲迭代有關。我們只想排列某個人對遊戲的特定迭代的最高分數,因爲某人可以在某個時候打破他們自己的分數並擁有多個記錄。以下查詢用於標記每個人對特定遊戲迭代的最高分數,以便它可以分開排列。在WHERE子句中使用子查詢進行MYSQL UPDATE查詢 - 優化

以下是極其緩慢的,我想加快速度:

/* 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

你可以這樣做沒有子查詢,使用MySQL的多表UPDATE語法。

使用OUTER JOIN,查找同一個人和varid的分數以及更高的分數。如果沒有找到更高的分數(即,如果m是具有最高分數的行),那麼外連接將使連接表的所有列爲空。

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;