Mit gebührendem Respekt an alle und an IMHO,
There is not much difference between While LOOP and Recursive CTE in terms of RBAR
Es gibt nicht viel Leistungsgewinn bei der Verwendung Recursive CTE
und Window Partition function
alles in einem.
Appid
sollte sein int identity(1,1)
, oder es sollte immer größer werden clustered index
.
Neben anderen Vorteilen wird auch sichergestellt, dass alle aufeinanderfolgenden Reihen APPDate
dieses Patienten größer sein müssen.
Auf diese Weise können Sie problemlos mit APPID
Ihrer Abfrage spielen, was effizienter ist, als inequality
Operatoren wie>, <in APPDate einzufügen. Das Einfügen von inequality
Operatoren wie>, <in APPID hilft dem SQL-Optimierer.
Außerdem sollte es in der Tabelle zwei Datumsspalten geben
APPDateTime datetime2(0) not null,
Appdate date not null
Da dies die wichtigsten Spalten in der wichtigsten Tabelle sind, konvertieren Sie nicht viel.
So Non clustered index
kann auf Appdate erstellt werden
Create NonClustered index ix_PID_AppDate_App on APP (patientid,APPDate) include(other column which is not i predicate except APPID)
Testen Sie mein Skript mit anderen Beispieldaten und ich weiß, für welche Beispieldaten es nicht funktioniert. Auch wenn es nicht funktioniert, bin ich sicher, dass es in meiner Skriptlogik selbst behoben werden kann.
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