Использование функции УДАЛИТЬ ИЗ с помощью РУКОВОДСТВА

#sql #sql-server #subquery #lead

Вопрос:

Используя SQL Server 2014, у меня есть таблица, которая отслеживает продажи кассовых аппаратов. Если оператор реестра сканирует элемент по ошибке, он создаст две записи — одну SALE запись и одну VOID запись.

 TRX_ID   LINE_ID   STS     ITEM_DESC
-----------------------------------------------------
123456   1         Sale    Sunglasses Mens RS124
123456   2         Void    Sunglasses Mens RS124
123456   3         Sale    Sunglasses NXR RS977
123456   4         Void    Sunglasses NXR RS977
123456   5         Sale    Sunglasses Unisex RS355

123678   1         Sale    Sunglasses Womens RS124w
123678   2         Void    Sunglasses Womens RS124w
123678   3         Sale    Sunglasses Womens RS977w
123678   4         Sale    Sunglasses Womens RS977w
123678   5         Sale    Sunglasses Unisex RS355w
 

Мне нужно написать запрос на удаление записей, если следующий элемент транзакции был аннулирован (STS= «НЕДЕЙСТВИТЕЛЕН»), сохраните только «чистые» транзакции.

Я использую LEAD запрос для проверки следующей записи, я просто не знаю, как объединить DELETE FROM и LEAD вместе. Я безуспешно пытался использовать этот запрос:

 DELETE FROM SALES 
WHERE xxx IN (SELECT 
                  TRX_ID, LINE_ID, LEAD (T1.STS, 1, 0) OVER (PARTITION BY T1.TRX_ID ORDER BY T1.LINE_ID)  NEXT_STS
              FROM SALES_TRANSACTIONS T1) 
WHERE NEXT_STS = 'V' 
 

Кроме результата: удаляются следующие записи:

 TRX_ID   LINE_ID   STS     ITEM_DESC
----------------------------------------------------
123456   1         Sale    Sunglasses Mens RS124
123456   2         Void    Sunglasses Mens RS124
123456   3         Sale    Sunglasses NXR RS977
123456   4         Void    Sunglasses NXR RS977
123678   1         Sale    Sunglasses Womens RS124w
123678   2         Void    Sunglasses Womens RS124w
 

Ответ №1:

Вы можете сделать это несколькими способами. Один из них состоит в том, чтобы использовать lead в общем табличном выражении, а затем удалить из него:

 with extra as (
    select sts,
           lead(sts) over (partition by trx_id order by line_id) leadsts
    from   sales
)
delete 
from   extra
where  'Void' in (sts, leadsts);