2013-07-26 40 views
0

希望你能幫助我與我同:)遍歷數據集在MySQL更新列

掙扎數據庫問題。假設我有一個表如下:

id | user_id | training_id | date    |  performance | best 
1 | 7042  | 11   | 2013-07-23 13:43:29 | 654   | true 
2 | 7042  | 11   | 2013-07-25 15:22:59 | 703   | false 
3 | 2344  | 12   | 2013-07-26 09:20:12 | 400   | true 
... 

表包含訓練(training_id)用戶(user_id)已經免除。當用戶放棄比以前所有訓練(training_id)更好的訓練時,他有最好的(best = true)。我現在想要添加一個輔助列'last_best',以便我可以查詢給定用戶的每次培訓的最後一個最佳值。爲了提供丟失last_pb的值,我想在數據庫中的所有培訓上運行腳本。

我的第一種方法是遍歷rails控制檯中的所有培訓和用戶。但是這種方法非常慢。大約70,000個用戶和200,000個培訓的數據集大約需要36個小時。

現在我想用SQL來做同樣的事情,但是我在迭代用戶和培訓方面掙扎不已。 希望你能幫助我。

+0

當你說:「當用戶放棄比以前所有培訓都更好的培訓(training_id)時,他有最好的(最好=真)」你是指每個用戶還是所有用戶? –

+0

我的意思是分別爲每個用戶(他爲他的訓練設定一個新記錄)。 – Psystorm

回答

0

下面的查詢確實使用變量MySQL中的排名:

select t.*, 
     @rn := if(@user_id <> USER_ID or @training_id <> training_id, @rn + 1, 1) as ranking, 
     @user_id := user_id, 
     @training_id := training_id 
from t cross join 
    (select @user_id := -1, @training_id := -1, @rn := 0) const 
order by USER_ID, training_id, performance desc; 

這無疑是你想要做什麼,最有效的方法。謹慎的一句話。雖然它在實踐中有效,但存在一個問題。 MySQL不保證參數評估的順序。該查詢取決於ranking在兩個變量賦值之前被評估。在實踐中,它們是按順序評估的,但這並不能保證。