Com o devido respeito a todos e no IMHO,
There is not much difference between While LOOP and Recursive CTE in terms of RBAR
Não há muito ganho de desempenho ao usar Recursive CTE
e Window Partition function
tudo em um.
Appid
deveria ser int identity(1,1)
, ou deveria estar sempre aumentando clustered index
.
Além de outros benefícios, também garante que todas as filas sucessivas APPDate
desse paciente sejam maiores.
Dessa forma, você pode facilmente brincar com APPID
sua consulta, o que será mais eficiente do que colocar o inequality
operador como>, <em APPDate. Colocar o inequality
operador como>, <no APPID ajudará o Sql Optimizer.
Também deve haver duas colunas de data na tabela como
APPDateTime datetime2(0) not null,
Appdate date not null
Como essas são as colunas mais importantes da tabela mais importante, então não muito elenco, converta.
Então Non clustered index
pode ser criado no Appdate
Create NonClustered index ix_PID_AppDate_App on APP (patientid,APPDate) include(other column which is not i predicate except APPID)
Teste meu script com outros dados de amostra e deixe-me saber para quais dados de amostra ele não está funcionando. Mesmo que não funcione, tenho certeza de que pode ser corrigido na minha própria lógica de script.
CREATE TABLE #Appt1 (ApptID INT, PatientID INT, ApptDate DATE)
INSERT INTO #Appt1
SELECT 1,101,'2020-01-05' UNION ALL
SELECT 2,505,'2020-01-06' UNION ALL
SELECT 3,505,'2020-01-10' UNION ALL
SELECT 4,505,'2020-01-20' UNION ALL
SELECT 5,101,'2020-01-25' UNION ALL
SELECT 6,101,'2020-02-12' UNION ALL
SELECT 7,101,'2020-02-20' UNION ALL
SELECT 8,101,'2020-03-30' UNION ALL
SELECT 9,303,'2020-01-28' UNION ALL
SELECT 10,303,'2020-02-02'
;With CTE as
(
select a1.* ,a2.ApptDate as NewApptDate
from #Appt1 a1
outer apply(select top 1 a2.ApptID ,a2.ApptDate
from #Appt1 A2
where a1.PatientID=a2.PatientID and a1.ApptID>a2.ApptID
and DATEDIFF(day,a2.ApptDate, a1.ApptDate)>30
order by a2.ApptID desc )A2
)
,CTE1 as
(
select a1.*, a2.ApptDate as FollowApptDate
from CTE A1
outer apply(select top 1 a2.ApptID ,a2.ApptDate
from #Appt1 A2
where a1.PatientID=a2.PatientID and a1.ApptID>a2.ApptID
and DATEDIFF(day,a2.ApptDate, a1.ApptDate)<=30
order by a2.ApptID desc )A2
)
select *
,case when FollowApptDate is null then 'New'
when NewApptDate is not null and FollowApptDate is not null
and DATEDIFF(day,NewApptDate, FollowApptDate)<=30 then 'New'
else 'Followup' end
as Category
from cte1 a1
order by a1.PatientID
drop table #Appt1