まず、あなたが日で作業するつもりならCalendar Tableを使用して検討すべきです。それは物事を簡素化します。
create table Calendar
(
id int primary key identity,
date datetime not null
--various computed date attributes that we elide for now...
)
--populate with few years worth of days:
declare @dt datetime
set @dt = '1/1/2017'
while @dt <= '12/31/2020'
begin
insert Calendar select @dt
set @dt = dateadd(day, 1, @dt)
end
が故に、あなたのスキーマは、おそらくこのようなものになります。このスキーマに関して
create table Drug
(
id int primary key identity,
name nvarchar(100) not null
)
create table Patient
(
id int primary key identity,
name nvarchar(100) not null
)
create table DrugTrial
(
patient int foreign key references Patient,
drug int foreign key references Drug,
date int foreign key references Calendar,
supply int
)
を、あなたのサンプルデータは、次のとおりです。
insert Patient select 'ABC'
insert Drug select 'A'
union select 'B'
insert DrugTrial
select 1, 1, 1, 30 union
select 1, 1, 31, 30 union
select 1, 2, 61, 30 union
select 1, 1, 91, 30
我々が設定された所望の結果を得ることができます単一の通常のクエリですが、わかりやすくするために、一連の共通テーブル式を使用します。
まず、前任者を持つすべての試行のセットを生成します。
with Q as
(
select T.* from DrugTrial S
cross apply
(
select * from DrugTrial T
where T.date = S.date + S.supply and
T.patient = S.patient and T.drug = S.drug
) T
),
は次に、我々はシーケンスの始めにあるトライアルのセットを計算する必要があります。これは、我々は同じ薬剤と患者との裁判の直後来る試練のすべてを望んでいることを意味します。しかし、それはすべての試行のセットだけであるので、これは簡単ですマイナス前任者(上で定義されているように、Q)を持つ試行のサブセットです。
P as
(
select patient, drug, date, supply from DrugTrial
except select patient, drug, date, supply from Q
),
最後に、配列を構築するために再帰クエリを使用:Rの
R as
(
select *, row_number() over (order by date) as seq from P
union all
select Q.*, S.seq from Q cross apply
(select * from R
where Q.date = R.date + R.supply
and Q.patient = R.patient and R.drug = Q.drug) S
)
ベースケースは、我々は順番にrow_number
機能を増強するだけでセットP、あります我々のシーケンス番号を生成する。 Rの再帰的ケースは、各試行の後続試行(もしあれば)をRに計算するだけです。一緒にすべてを置く
:
select
Pt.id patient_id, Pt.name patient_name,
D.id drug_id, D.name drug_name,
R.supply, R.date, R.seq
from R inner join Patient Pt on Pt.id = R.patient
inner join Drug D on D.id = R.drug
inner join Calendar C on C.id = R.date order by R.date
は結果が得られます。
patient_id patient_name drug_id drug_name supply date seq
----------- ---------------- ----------- ------------- ----------- ------ ---
1 ABC 1 A 30 1 1
1 ABC 1 A 30 31 1
1 ABC 2 B 30 61 2
1 ABC 1 A 30 91 3
あなたは、ソリューション全体hereを見ることができます。コミットされていないトランザクションに包まれているため、簡単に遊ぶことができます。
使用しているデータベースにタグを付けてください。 –