Как определить строки, которые происходят в течение определенного периода времени? - PullRequest
5 голосов
/ 01 мая 2019

У меня есть таблица, которая содержит посещения больниц для пациентов. Я пытаюсь отметить посещения, которые произошли в течение 90 дней с момента предыдущего посещения. Однако предостережение заключается в том, что если посещение помечается как посещение с перекрытием, то такое посещение не должно использоваться для оценки совпадения с другим посещением. Позвольте мне объяснить на примере.

Таблица

visitID     patientid    visit_date  
1           23           1/12/2018
2           23           1/30/2018
3           23           4/20/2018
4           23           5/02/2018

В приведенном выше примере пациентка была 4 раза. Визит 2 был в течение 90 дней после визита 1, поэтому визит 2 должен быть отмечен как перекрывающийся. После того, как посещение 2 помечено, эта строка не должна использоваться в анализе для идентификации перекрытия для любых будущих посещений. Концептуально это все равно, что удалить визит 2 и начать анализ заново.

промежуточный этап (посещение 2 удалено, и анализ начинается снова)

visitID     patientid    visit_date  
1           23           1/12/2018
3           23           4/20/2018
4           23           5/02/2018

Таким образом, несмотря на то, что посещение 3 частично совпадает с посещением 2, так как посещение 2 было исключено из анализа, посещение 3 не будет помечено, поскольку предыдущее посещение (посещение 1) прошло более чем через 90 дней. Наконец, посещение 4 должно быть помечено, поскольку оно совпадает с посещением, которое не было отмечено.

Ожидаемый результат

visitID     patientid    visit_date flag
1           23           1/12/2018  0
2           23           1/30/2018  1
3           23           4/20/2018  0 
4           23           5/02/2018  1

Моя попытка разгадать эту загадку:

WITH overlaps AS 
    (SELECT DISTINCT T2.visit
    FROM visits_table AS T1
    INNER JOIN visits_table AS T2
            ON T1.visit != T2.visit
                AND T2.visit_date BETWEEN T1.visit_date AND DATEADD(DAY, 89, T1.visit_date))

    SELECT T3.visit, T3.patientid, T3.visit_date,
    CASE WHEN EXISTS (SELECT 1 FROM overlaps
                        WHERE overlaps.visit = T3.visit) 
                THEN 1
                ELSE 0
                END flag
    FROM visits_table T3

Мой код проверяет каждую строку независимо от того, должна ли она использоваться в анализе. Я не знаю, как сделать его динамическим, чтобы он игнорировал строки, которые следует игнорировать.

Dataset:

create table visits_table (visit int,patientid int,visit_date date);

INSERT INTO visits_table (visit, patientid, visit_date) VALUES (1,23,'1/12/2018')
INSERT INTO visits_table (visit, patientid, visit_date) VALUES (2,23,'1/30/2018')
INSERT INTO visits_table (visit, patientid, visit_date) VALUES (3,23,'4/20/2018')
INSERT INTO visits_table (visit, patientid, visit_date) VALUES (4,23,'5/02/2018')

1 Ответ

6 голосов
/ 01 мая 2019

Я полагаю, что вы должны сделать это с рекурсивным CTE:

with vt as (
      select vt.*, row_number() over (partition by patientid order by visit_date) as seqnum
      from visits_table vt
     ),
     cte as (
      select vt.visit, vt.patientid, vt.visit_date, vt.visit_date as first_visit_date, seqnum
      from vt
      where seqnum = 1
      union all
      select vt.visit, vt.patientid, vt.visit_date,
             (case when vt.visit_date > dateadd(day, 90, cte.first_visit_date) then vt.visit_date else cte.first_visit_date end),
             vt.seqnum
      from cte join
           vt
           on vt.seqnum = cte.seqnum + 1 and vt.patientid = cte.patientid
     )
select cte.visit, cte.patientid, cte.visit_date,
       (case when first_visit_date = visit_date then 0 else 1 end) as flag
from cte
order by cte.patientid, cte.visit_date;

Здесь - это скрипта db <>.

...