I need add the days of medication for people over the course of a year and determine how many days were covered by medication.
This is similar to a Gaps and Islands problem except that people don't wait till the last day of their previous prescription before getting a new one so the days' supply needs to be added from the initial dispense date to determine a date range. To further complicate it, they are allowed a 7-day gap of no medication to still be considered covered.
The measure is met when the member adheres to OUD pharmacotherapy for 180 days or more without a gap in treatment of more than eight days
The closest I got was using Preceding and but it only added the days for the ones around it not the entire group. I need to add all the Days supply of medication to the first Date of Service for a person in which the DOS is covered by the medication range.
;WITH TBL AS (
SELECT CAST('2022-01-24' AS DATE) AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-02-12' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-03-01' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-04-01' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-05-12' AS DOS, 60 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-07-02' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-08-08' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-09-24' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-10-21' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-11-22' AS DOS, 30 AS DAYS, 'John' F_NAME
UNION
SELECT '2022-02-16' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-03-11' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-04-30' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-05-22' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-06-10' AS DOS, 60 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-08-20' AS DOS, 60 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-09-24' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-10-21' AS DOS, 30 AS DAYS, 'Mary' F_NAME
UNION
SELECT '2022-12-10' AS DOS, 30 AS DAYS, 'Mary' F_NAME
)
SELECT F_NAME, MIN(DOS), MAX(EDOS) , DATEADD(DAY, SUM(DAYS), MIN(DOS))
FROM (
SELECT F_NAME, DOS, EDOS, DAYS, SUM(ADD1) OVER(PARTITION BY F_NAME ORDER BY DOS,EDOS ROWS UNBOUNDED PRECEDING) AS GRP
FROM ( SELECT *, DATEADD(DAY, DAYS, DOS) AS EDOS,
IIF(DOS <= MAX(DATEADD(DAY, DAYS, DOS))OVER(PARTITION BY F_NAME ORDER BY DOS, DATEADD(DAY, DAYS, DOS) ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0, 1) AS ADD1 FROM TBL ) AS A
) AS G
GROUP BY F_NAME, GRP
In the example data...
DOS | DAYS | F_NAME |
---|---|---|
2022-01-24 | 30 | John |
2022-02-12 | 30 | John |
2022-03-01 | 30 | John |
2022-04-01 | 30 | John |
2022-05-12 | 60 | John |
2022-07-02 | 30 | John |
2022-08-08 | 30 | John |
2022-09-24 | 30 | John |
2022-10-21 | 30 | John |
2022-11-22 | 30 | John |
2022-02-16 | 30 | Mary |
2022-03-11 | 30 | Mary |
2022-04-30 | 30 | Mary |
2022-05-22 | 30 | Mary |
2022-06-10 | 60 | Mary |
2022-08-20 | 60 | Mary |
2022-09-24 | 30 | Mary |
2022-10-21 | 30 | Mary |
2022-12-10 | 30 | Mary |
... there should only be one range for John (2022-01-24
- 2022-12-20
) since he was covered all year. He did have a gap from 2022-09-22
- 2022-09-23
and 2022-11-21
but they would be covered by the 7-day exception. Mary would have two islands - 2022-02-16
to 2022-04-17
, 2022-04-30
to 2022-06-12
(since the 2022-08-29
- 2022-09-02
gap is less than 7 days).
Any help getting any closer would be appreciated. I've looked but haven't found similar questions where the total days need to be added to the initial date.
I'm using SQL server 2019.