Как удалить перекрывающиеся строки на основе даты и сохранить последние в SQL? - PullRequest
0 голосов
/ 02 июля 2018

Мне нужно найти все episode_ids для каждого пациента. Однако, когда эпизод с перекрытием возникает в течение 90 дней с момента предыдущего, я просто хочу сохранить самый последний эпизод.

Например, patient_num 3242 ниже имеет 3 эпизода: второй эпизод перекрывается с первым эпизодом в течение 90 дней, а третий эпизод перекрывается со вторым эпизодом в течение 90 дней, в этой ситуации мне нужно просто сохранить третий эпизод ,

CREATE TABLE table1 (episode_id nvarchar(max), patient_num nvarchar(max), admit_date date,  discharge_date date)

INSERT INTO table1 (episode_id, patient_num , admit_date ,  discharge_date ) VALUES 
('1','5743','1/1/2016','1/5/2016'),
('2','5743','4/26/2016','4/29/2016'),
('3','5743','5/26/2016','5/28/2016'),
('4','5743','9/21/2016','9/28/2016'),
('5','8859','4/27/2016','5/5/2016'),
('6','3242','4/28/2016','4/29/2016'),
('7','3242','11/21/2016','11/23/2016'),
('8','3242','11/24/2016','11/29/2016'),
('9','3242','12/12/2016','12/29/2016')

Исходная таблица (таблица1)

episode_id   patient_num  admit_date   discharge_date
1            5743         2016-01-01   2016-01-05 
2            5743         2016-04-26   2016-04-29
3            5743         2016-05-26   2016-05-28
4            5743         2016-09-21   2016-09-28
5            8859         2016-04-27   2016-05-05
6            3242         2016-04-28   2016-04-29
7            3242         2016-11-21   2016-11-23
8            3242         2016-11-24   2016-11-29
9            3242         2016-12-12   2016-12-29

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

episode_id   patient_num  admit_date   discharge_date
1            5743         2016-01-01   2016-01-05 
3            5743         2016-05-26   2016-05-28
4            5743         2016-09-21   2016-09-28
5            8859         2016-04-27   2016-05-05
6            3242         2016-04-28   2016-04-29
9            3242         2016-12-12   2016-12-29

Моя попытка:

SELECT *
FROM table1 AS a
WHERE EXISTS
(
    SELECT *
    FROM table1 AS b
    WHERE      a.episode_id != b.episode_id
               AND a.patient_num= b.patient_num
               AND a.admit_date BETWEEN b.discharge_date AND DATEADD(DAY, 90, b.discharge_date ))

Ошибка в моем сценарии заключается в том, что для номера пациента 3242 я получаю оба эпизода с идентификаторами эпизодов 8 и 9, где я хочу только эпизод 9. Я предполагаю, что причина этой ошибки в том, что вместо этого я сравниваю каждую строку отдельно из группы, но у меня проблемы с группировкой. Кроме того, этот сценарий не показывает случаи, когда нет перекрытия, например, episode_id 1, 4, 5, 6. Любые рекомендации по этому подходу?

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Я думаю not exists делает то, что вы хотите:

SELECT a.*
FROM table1 a
WHERE NOT EXISTS (SELECT 1
                  FROM table1 b
                  WHERE a.episode_id <> b.episode_id AND
                        a.patient_num = b.patient_num AND
                        b.admin_date < a.discharge_date AND
                        b.discharge_date >= DATEADD(DAY, -90, a.discharge_date)
                 );
0 голосов
/ 02 июля 2018

Я удалил решение курсора здесь, так как оно имеет низкую производительность решение без использования курсора:

WITH ExcludedIds AS (
SELECT DISTINCT T2.episode_id 
FROM table1  AS T 
INNER JOIN table1 AS T2 ON T.episode_id != T2.episode_id
               AND T.patient_num = T2.patient_num
               AND T2.discharge_date BETWEEN DATEADD(DAY, -90, T.admit_date ) AND  T.discharge_date)

SELECT T.episode_id, T.patient_num, T.admit_date, T.discharge_date 
FROM table1 AS T 
WHERE T.episode_id NOT IN (SELECT ExcludedIds.episode_id FROM ExcludedIds)

Мысль понять это решение немного сложно.

...