2010-02-02 48 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