Considere el uso de lo que se llama CTE (expresión de tabla común) (consulte el documento de MSDN):
;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