Функция окна SQL для удаления нескольких значений с разными критериями - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть набор данных, в котором я пытаюсь удалить записи со следующими условиями:

Если на практике есть несколько записей с одинаковой датой и хотя бы одна запись имеет причину "L & B", тоЯ хочу, чтобы все данные на эту дату были удалены.

DECLARE t table(practid int, statusdate date, reason varchar(100)

INSERT INTO t VALUES (1, '2018-03-01', 'L&B'),
                     (1, '2018-03-01', 'NULL'),
                     (1, '2018-04-01, 'R&D'),
                     (2, '2018-05-01, 'R&D'),
                     (2, '2018-05-01, 'R&D'),
                     (2, '2018-03-15', NULL),
                     (2, '2018-03-15', 'R&D),
                     (3, '2018-07-01, 'L&B)

С этим набором данных я бы хотел получить следующий результат:

PractId  StatusDate   Reason
1         2018-04-01   R&D
2         2018-05-01   R&D
2         2018-05-01   R&D
2         2018-03-15    NULL
2         2018-03-15   R&D

Я пытался решить эту проблему с помощью оконной функции, ноя застреваю:

SELECT *, ROW_NUMBER() OVER
    (PARTITION BY practid, statusdate, CASE WHEN reason = 'L&B' THEN 0 ELSE 1 END) AS rn
FROM table

Из моего запроса я не могу понять, как сохранить Practid = 2, так как я хотел бы сохранить все записи.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Чтобы продолжить ваш текущий подход, мы можем использовать COUNT в качестве аналитической функции.Мы можем подсчитать случаи возникновения причины L&B по каждому окну practid/statusdate, а затем сохранить только те группы, в которых эта причина никогда не возникает.

SELECT practid, statusdate, reason
FROM
(
    SELECT *,
        COUNT(CASE WHEN reason = 'L&B' THEN 1 END) OVER
            (PARTITION BY practid, statusdate) cnt
    FROM yourTable
) t
WHERE cnt = 0;

Демонстрация

0 голосов
/ 24 сентября 2018

Вы можете попробовать использовать not exists с подзапросом.

 Select *
 from t t1
 where not exists (
     select 1 
     from t tt
     where tt.reason = 'L&B' and t1.statusdate = tt.statusdate
 )

sqlfiddle

...