2010-07-07 17 views
9

我試圖讓我的頭繞着一個查詢,我只是無法弄清楚。如果有人給我一個指針,我將不勝感激。由於我想要實現一個簡單的例子,我在數據庫MySQL更新聲明來存儲排名位置

Score|Ranking 
------------- 
100 |0 
200 |0 
300 |0 

有這些記錄,我想基於誰的得分最高,因此上榜場包含1,2,3結果應該是:

Score|Ranking 
------------- 
100 |3 
200 |2 
300 |1 

目前,我正在做一個爲下一個循環對所有這些記錄,但考慮到在現實中可能是幾千 - 這可能需要永遠!有沒有人有一個神奇的查詢,這將一舉做到這一點的想法?

回答

4

在MySQL中,您可以使用row_number

SELECT使用它的Here's an example:如果您INSERT INTO使用SELECT這樣

select @rownum:[email protected]+1 ‘rank’, p.* 
from player p, (SELECT @rownum:=0) r 
order by score desc; 

,你會得到你的排名。

+0

+1:通常我會說這應該是在視圖中,但MySQL視圖不允許變量使用。還有一種替代方法是在子查詢中使用COUNT來獲得在我想象的視圖中能夠工作的排名值... – 2010-07-07 17:10:52

+10

這在哪裏更新了數據庫中的值? – quantumSoup 2010-07-07 17:39:18

4

這將創建一個內聯更新語句,該語句將根據變量@rc對玩家進行排名。我在非常相似的情況下多次使用過它,它運行良好,並保持在數據庫端。

SET @rc = 0; 
UPDATE players JOIN (SELECT @rc := @rc + 1 AS rank, id FROM players ORDER BY rank DESC) 
AS order USING(id) SET players.rank = order.rank; 

id被假定爲您players表的主鍵。

16

這裏有一個辦法做到這一點:

SET @r=0; 
UPDATE table SET Ranking= @r:= (@r+1) ORDER BY Score DESC; 

/* use this if you just want to pull it from the db, but don't update anything */ 
SET @r=0; 
SELECT *, @r:= (@r+1) as Ranking FROM table ORDER BY Score DESC; 
+1

查看DOK的版本 - 它不需要SET語句,它完全獨立。 – 2010-07-07 17:47:57

+2

自我包含在一個查詢中,是的;但那是因爲他在SELECT子查詢中設置了@rownum。我認爲這看起來更混亂。 – quantumSoup 2010-07-07 17:55:23

+0

美在審視者眼中,但提交單一陳述的能力不太可能有問題 – 2010-07-07 23:17:11

0

我展示你我做這件事的方式[區間SQL更新功能]

選擇:

set @currentRank = 0, 
    @lastRating = null, 
    @rowNumber = 1; 
select 
    *, 
    @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`, 
    @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`, 
    @lastRating := `score` 
from `table` 
order by `score` desc 

更新:

set @currentRank = 0, 
    @lastRating = null, 
    @rowNumber = 1; 
update 
    `table` r 
    inner join (
     select 
      `primaryID`, 
      @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`, 
      @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`, 
      @lastRating := `score` 
     from `table` 
     order by `score` desc 
    ) var on 
     var.`primaryID` = r.`primaryID` 
set 
    r.`rank` = var.`rank` 

i沒有進行任何性能檢查,除了測試它的工作

2
SET @r = 0; 
UPDATE players JOIN (SELECT @r := @r + 1 AS rank, id FROM players ORDER BY rank DESC) 
AS sorted USING(id) SET players.rank = sorted.rank;