2010-10-12 132 views
15

我是SQL Server开发新手。我的大部分经验都是通过Oracle完成的。SQL Server递归查询

假设我有一个包含约会下表对象

CREATE TABLE [dbo].[Appointments](
    [AppointmentID] [int] IDENTITY(1,1) NOT NULL, 
    ....... 
    [AppointmentDate] [datetime] NOT NULL, 
    [PersonID] [int] NOT NULL, 
    [PrevAppointmentID] [int] NULL, 
CONSTRAINT [PK_Appointments] PRIMARY KEY CLUSTERED ([AppointmentID] ASC) 

的约会可以推迟所以,当这一切发生时,与包含原始的ID的PrevAppointmentID字段的表创建一个新的行约定。

我想查询一个人约会的历史记录。例如,如果ID = 1的任命推迟了两次,并且这些延期已为同一PersonID创建了ID = 7和ID = 12的约会,我想进行查询以返回以下结果:

AppointmentID   PrevAppointmentID 
----------------- ---------------------- 
1      NULL 
7      1 
12     7 

如果使用Oracle,我记得使用CONNECT BY PRIOR子句可以得到类似这样的东西。

有什么办法可以做出查询来实现这些结果吗?

我正在使用SQL Server 2005/2008。

在此先感谢

回答

18

考虑使用所谓的CTE(公共表表达式)(参见MSDN document):

;with cteAppointments as (
select AppointmentID, PersonID, PrevAppointmentID 
    from Appointments 
    where PrevAppointmentID is null 
union all 
select a.AppointmentID, a.PersonID, a.PrevAppointmentID 
    from Appointments a 
     inner join cteAppointments c 
      on a.PrevAppointmentID = c.AppointmentID 
) 
select AppointmentID, PrevAppointmentID 
    from cteAppointments 
    where PersonID = xxx