Con el debido respeto a todos y en mi humilde opinión,
There is not much difference between While LOOP and Recursive CTE in terms of RBAR
No hay mucho aumento de rendimiento cuando se usa Recursive CTE
y Window Partition function
todo en uno.
Appid
debería ser int identity(1,1)
, o debería estar aumentando cada vez más clustered index
.
Además de otros beneficios, también asegura que todas las filas sucesivas APPDate
de ese paciente deben ser mayores.
De esta manera, puede jugar fácilmente APPID
en su consulta, que será más eficiente que poner inequality
operador como>, <en APPDate. Poner al inequality
operador como>, <en APPID ayudará a Sql Optimizer.
También debe haber dos columnas de fecha en la tabla como
APPDateTime datetime2(0) not null,
Appdate date not null
Como estas son las columnas más importantes en la tabla más importante, entonces no hay mucho reparto, conversión.
Entonces Non clustered index
se puede crear en Appdate
Create NonClustered index ix_PID_AppDate_App on APP (patientid,APPDate) include(other column which is not i predicate except APPID)
Pruebe mi script con otros datos de muestra y déjeme saber para qué datos de muestra no funciona. Incluso si no funciona, estoy seguro de que puede solucionarse en la lógica de mi 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