2012-05-21 101 views
0

我在SQL Server 2005中的一個問題:SQL Server 2005中RANK函數

假設我有表PLAYERstring player, int score, bool Active)與此查詢:

SELECT PLAYER.player AS NAME, 
    PLAYER.score AS SCORE, 
    POSITION = CASE WHEN PLAYER.Active THEN RANK()OVER(ORDER BY score desc) else NULL end 
from PLAYER 

的問題是,當玩家不活躍,產生的頭寸不連續。

例如:

JOHN,10000,1 
PETER,5000,NULL (NOT ACTIVE) 
CHARLES,2500,3 (SHOULD HAVE POSITION 2, NOT 3) 

對不起,我的可怕的英語,我希望我解釋我的觀點

+0

不活躍球員的排名怎麼樣?你想排名嗎?還是隻想排名現役球員? –

+0

我想排名只有活躍的球員。不活動必須具有空值非位置列 –

回答

2
declare @Player table 
(
    player varchar(20), 
    score int, 
    state int 
) 

insert into @Player values ('JOHN', 10000, 1) 
insert into @Player values ('PETER', 5000, NULL) 
insert into @Player values ('PAUL', 5000, 2) 
insert into @Player values ('CHARLES', 2500, 1) 

select player as Name, 
     score, 
     case 
      when state = 1 then 
      rank() over(partition by state order by score desc) 
      else null 
     end as position 
from @Player  

結果:

Name     score  position 
-------------------- ----------- -------------------- 
PETER    5000  NULL 
JOHN     10000  1 
CHARLES    2500  2 
PAUL     5000  NULL 
+0

只要位類型不會轉換爲int(因爲它已經具有大於1的值)。 –

+0

@TimSchmelter爲什麼/何時將其轉換爲int? –

+0

我認爲活動是一種狀態,因爲OP使用的值爲1,NULL和3.這聽起來像它實際上是一個'int'(或將)。如果它將被更改爲「int」數據類型,那麼排名將會是錯誤的,因爲OP要按比分不活躍(先按比分活躍,然後是非活躍)來排序。 –

1

試試這個:

POSITION = 
    RANK()OVER(ORDER BY CASE WHEN Active IS NULL THEN 1 ELSE 0 END ASC, score DESC) 

編輯

...但問題是,其實我的「活動」一欄是不是布爾, 真正的列名爲「狀態」的整數,它必須等於1是 活性。在這種情況下,代碼應該如何?

那麼這應該工作:

POSITION = 
    RANK()OVER(ORDER BY CASE WHEN State = 1 THEN 0 ELSE 1 END ASC, score DESC) 
+0

,沒有工作,我得到了非活動專欄的最高職位 –

+0

@ martin.softpro:我無法複製此信息,此信息通過活躍的最高分獲得,然後停用最高分。當然,這並不會返回null。無論如何,我看到你得到它的工作:) –

0

試試這個:

SELECT PLAYER.player AS NAME, 
PLAYER.score AS SCORE, 
POSITION = RANK()OVER(ORDER BY score desc) 
from PLAYER 
WHERE ACTIVE IS NOT NULL 
UNION 
SELECT PLAYER.player AS NAME, 
PLAYER.score AS SCORE,NULL 
from PLAYER 
WHERE ACTIVE IS NULL 

我不知道如何高效相比已經回答查詢時,這將是,但它是一個更容易一些瞭解。