Herkese ve IMHO'ya saygıyla,
There is not much difference between While LOOP and Recursive CTE in terms of RBAR
Kullanırken çok fazla performans kazancı yok Recursive CTE
ve Window Partition function
hepsi bir arada.
Appid
olmalı int identity(1,1)
ya da sürekli artmalıdır clustered index
.
Diğer faydalarının yanı sıra APPDate
, hastanın ardışık tüm sırasının daha büyük olması da sağlar.
Bu şekilde APPID
sorgunuzda kolayca oynayabilirsiniz ki bu inequality
, APPDate'e>, <gibi bir operatör koymaktan daha verimli olacaktır . inequality
Operatörü APPID'ye>, <gibi koymak Sql Optimizer'a yardımcı olacaktır.
Ayrıca tabloda iki tarih sütunu olmalıdır.
APPDateTime datetime2(0) not null,
Appdate date not null
Bunlar en önemli tabloda en önemli sütunlar olduğundan, çok fazla döküm değil, dönüştürün.
Yani Non clustered index
Appdate üzerinde oluşturulabilir
Create NonClustered index ix_PID_AppDate_App on APP (patientid,APPDate) include(other column which is not i predicate except APPID)
Scriptimi diğer örnek verilerle test edin ve hangi örnek veriler için çalışmadığını biliyorum. Çalışmasa bile, komut dosyası mantığımın kendisinde düzeltilebileceğinden eminim.
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