2010-02-02 62 views
0

我需要一個SQL查詢,它返回每個ClientID的PlanDate的前2個計劃。這是所有在PlanID是PrimaryID,ClientID是一個foreignID。SQL查詢,按外部鍵排序按日期排序前2 2

這是我迄今爲止 - >

SELECT * 
FROM [dbo].[tblPlan] 
WHERE [PlanID] IN (SELECT TOP (2) PlanID FROM [dbo].[tblPlan] ORDER BY [PlanDate] DESC) 

顯然,這隻能返回2條記錄,我確實需要最多2個記錄每ClientID

回答

5

這可以通過使用ROW_NUMBER來完成:

SELECT PlanId, ClientId, PlanDate FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY ClientId ORDER BY PlanDate DESC) rn, * 
    FROM [dbo].[tblPlan] 
) AS T1 
WHERE rn <=2 

添加任何其他列你需要選擇以獲得這些。

3

編輯,12月2011.更正CROSS應用解決方案

嘗試既看到什麼是最好的

SELECT * 
FROM 
    (-- distinct ClientID values 
    SELECT DISTINCT ClientID 
    FROM [dbo].[tblPlan] 
) P1 
    CROSS APPLY 
    (-- top 2 per ClientID 
    SELECT TOP (2) P2.PlanID 
    FROM [dbo].[tblPlan] P2 
    WHERE P1.ClientID = P2.ClientID 
    ORDER BY P2.[PlanDate] DESC 
) foo 

或者

;WITH cTE AS (
    SELECT 
    *, 
    ROW_NUMBER() OVER (PARTITION BY clientid ORDER BY [PlanDate] DESC) AS Ranking 
    FROM 
    [dbo].[tblPlan] 
) 
SELECT * FROM cTE WHERE Ranking <= 2 
+0

嗯,感謝,但我得到這個消息'102,級別15,狀態1,行5 附近有語法錯誤)'' – 2010-02-02 20:55:04

+0

@Refracted聖騎士:我的錯誤,需要在「應用於」別名表 – gbn 2010-02-02 20:56:08

+0

有趣的是,你的第二個選項和Mark Byers選項每個返回7062行。您的第一個選項返回21948行。關於差距的想法? – 2010-02-02 20:58:50