2016-01-21 29 views
4

我目前使用此查詢找到一個球員的排名:在這個分數表中查找我以前的排名會是一個好的查詢?

select 
    coalesce(
     (
      select count(1) 
      from scores b 
      where 
       b.top > a.top OR 
       (
        b.top = a.top AND 
        b.time < a.time 
       ) 
     ), 0 
    ) + 1 Rank 
from 
    Scores a 
where 
    user = ? 

我有一個評分表是這樣的:

id   int 
user   varchar(100) 
time   int (timestamp) 
top   int 

而且最近的表是這樣的:

id   int 
user   varchar(100) 
time   int (timestamp) 
score  int 
istopscore int (boolean 1/0) 

數據庫已經充滿了數據,所以我不能簡單地改變數據庫的結構。最近的表格中有超過200,000行,因此排序需要很長時間。我正試圖儘快找到一種方法來做到這一點。

我將如何找到球員的上一個等級?這是我曾嘗試:

select 
    coalesce(
     (
      select count(1) 
      from recent b 
      where 
       b.istopscore = 1 AND 
       (
        (
         b.score > a.top AND 
         b.time <= a.time 
        ) OR 
        (
         b.score = a.top AND 
         b.time < a.time 
        ) 
       ) 
      ), 0) + 1 Rank 
from scores a 
where user = ? 

與此查詢的問題是,如果用戶已經打進了多個新的最高分,它計算所有的人,所以它沒有給出正確的結果。

任何幫助將不勝感激。

+0

你可以創建一個[SQL小提琴(http://sqlfiddle.com)爲例? –

+1

@RobbieAverill http://sqlfiddle.com/#!9/0bc381/2 – Z0q

+0

你可以定義'以前的排名'好一點嗎? 「以前的排名」是什麼,是「這個用戶目前的排名會忽略他們的最高分?」還是「這個用戶在時間t排名是什麼?」 – Scott

回答

1

我認爲你的查詢幾乎是正確的。爲了克服多重頂的得分問題,則可以使用count(distinct username),像this

select 
    coalesce(
     (
      select count(distinct username) 
      from recent b 
      where 
       b.istopscore = 1 AND 
       (
        (
         b.score > a.top AND 
         b.time <= a.time 
        ) OR 
        (
         b.score = a.top AND 
         b.time < a.time 
        ) 
       ) 
      ), 0) + 1 Rank 
from scores a 
where username = 'Echo' 
+0

完美!謝謝 :) – Z0q

相關問題