This type of calculation is cumbersome in SQL Server because the date functions are clunky and there is no least()
or greatest()
function.
But, you can do it. It is essentially a self join with an aggregation. The key idea is determining the days of overlap. The beginning and ending of the overlap period is either the dos
or dos + days_supply
. This is just a complex case
statement:
select t.member, t.drug_id, t2.drug_id,
sum(datediff(day, (case when t.dos <= t2.dos then t2.dos else t.dos end),
(case when dateadd(day, t.days_supply, t.dos) <= dateadd(day, t2.days_supply, t2.dos)
then dateadd(day, t.days_supply, t.dos)
else dateadd(day, t2.days_supply, t2.dos)
end)
) as days_overlap
from table t join
table t2
on t.member = t2.member and t.drug_id < t2.drug_id and
t.dos between dateadd(day, -t.days_supply, t2.dos) and
dateadd(day, t2.days_supply, t2.dos)
group by t.member, t.drug_id, t2.drug_id;
The code might have an off-by-one error -- overlaps are always a bit confusing, but some real data usually clears things up quickly.
Note: This assumes that the drugs do not overlap with themselves. This is an important assumption; otherwise the days of overlaps will be overcounted.