2015-10-12 101 views
4

我試圖使用SQL函數Rank()來獲取列表幾個組的最高記錄。這裏是什麼即時通訊特林不起作用:SQL排名不能按預期工作

select hc.hId, hc.DpId, hc.Rank 
from (
    select d.hId, DpId, Rank() 
     OVER (Partition by DpId ORDER BY d.hId) AS Rank 
    FROM CurDp d 
    INNER JOIN HostList h on d.DpId = h.hId 
    INNER JOIN Coll_hList pch on d.hId = pch.hId 
    where h.Model = 'PRIMARY' 
) hc where hc.Rank <= 10 

我得到的前10條記錄如下:

HId | DpId | Rank 
-------x------x------ 
    7  | 590 | 1 
    18 | 590 | 2 
    23 | 590 | 3 
    24 | 590 | 4 
    26 | 590 | 5 
    36 | 590 | 6 
    63 | 590 | 7 
    80 | 590 | 8 
    84 | 590 | 9 
    88 | 590 | 10 

但是當我使用CROSS APPLY,這是我所需要的功能,因爲我得那種對不同型號的記錄,我用這個代碼:

select pch.hId, cc.DpId, cc.Rank from from Coll_hList pch 
cross apply 
(
    select hc.hId, hc.DpId, hc.Rank 
    from (
     select d.hId, DpId, Rank() 
      OVER (Partition by DpId ORDER BY d.hId) AS Rank 
     FROM CurrDp d 
     INNER JOIN HostList h on d.DpId = h.hId 
     where h.Model = 'PRIMARY' and d.hId = pch.hId 
    ) hc where hc.Rank <= 10 
) cc 

在這裏,我總是得到排名1,它不過濾嘴(沒有顯示整個結果):

HId | DpId | Rank 
-------x------x------ 
7  590 1 
18  590 1 
23  590 1 
24  590 1 
26  590 1 
36  590 1 
63  590 1 
80  590 1 
84  590 1 
88  590 1 
124  590 1 
125  590 1 
133  590 1 

我做錯了嗎?是否因爲CROSS APPLY?

我也使用dense_rank()而不是rank(),但它顯示相同的結果。

任何幫助實現這個請求與CROSS APPLY將不勝感激。

感謝

回答

4

在第一種情況下,你加入的Coll_hList並得到一個結果集,然後是排在10餘項。

在第二種情況下,在您的應用子選擇中,您只創建一個條目結果集。該排名結果排名第一。

你的排名已經在外部語句來完成:

select pch.hId, cc.DpId, Rank() 
      OVER (Partition by cc.DpId ORDER BY cc.hId) AS Rank 
from Coll_hList pch 
cross apply 
(
     select d.hId, DpId 
     FROM CurrDp d 
     INNER JOIN HostList h on d.DpId = h.hId 
     where h.Model = 'PRIMARY' and d.hId = pch.hId 

) cc 
+0

你好,謝謝你的答案,那偉大工程。我只是不明白你的「一次入場結果集」。你的意思是排名方法只能看到一個不能排序的結果嗎? – Aeron

+0

正是。交叉應用語法爲先前執行的聯接計算的結果集的每一行創建某種「臨時表」(至少它有助於以此方式思考),然後僅與該特定行聯接。在你的情況下,臨時表只有一行。 – flo