Удалите повторяющиеся строки в Oracle SQL, оставив последние записи - PullRequest
1 голос
/ 24 марта 2020

Я использую следующие SQL для идентификации дубликатов в таблице'action_list '. Это работает отлично. Теперь я хочу удалить все дубликаты из этой таблицы на основе этих критериев и оставить только самые последние записи. Они могут быть идентифицированы по столбцу last_update. Я пробовал разные операторы DELETE, но это не сработало. Любые предложения высоко ценятся.

SELECT par_num
,tran_num
,COUNT(*) AS num_duplicates
FROM transaction_list
WHERE last_update >= to_date('01-mar-2020 00:00:00', 'dd-mon-yyyy 
hh24:mi:ss')
GROUP BY par_num
,tran_num
HAVING COUNT(*) > 1
ORDER BY par_num

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Если идея состоит в том, чтобы удалить все дубликаты par_num / tran_num, кроме последнего в каждом наборе, упорядоченном по last_update, то это должно сделать это:

delete transaction_list
where  rowid in
       ( select lag(rowid)
                over (partition by par_num, tran_num order by last_update)
         from   transaction_list );

DBFiddle

Объяснение: lag возвращает значение из предыдущей строки (или другой более ранней строки - вы можете указать все виды логики смещения c, если хотите, но здесь мы просто хочу предыдущий ряд). Предложение over() определяет порядок и порядок окон. В этом случае мы хотим упорядочить каждый набор комбинаций par_num / tran_num на last_update и удалить предыдущую строку. Раздел partition by означает, что порядок сбрасывается для каждой комбинации par_num / tran_num, поэтому у каждой группы есть «последняя» строка, которая не будет удалена.

1 голос
/ 24 марта 2020

Вот подход, использующий идентификаторы строк:

delete from transaction
where 
    last_update = date '2020-03-01'
    and rowid in (
        select rid
        from (
            select 
                rowid rid, 
                row_number() over(partition by par_num ,tran_num order by last_update desc) rn
            from transaction                
        ) t
        where rn > 1
    )

Подзапрос генерирует список идентификаторов строк для строк, которые не являются последними в их группе (ie все записи, имеющие одинаковые par_num ,tran_num) - самая последняя запись на группу определяется с помощью row_number(). Внешний запрос просто удаляет эти строки.

...