Если у вас есть только небольшое количество дублирующихся строк, предпочтительнее будет использовать альтернативный подход вместо обновления / удаления.
Поэтому сначала проверьте количество дублированных строк
with clean as (
select CUSTOMER_ID, TYPE, max(start_date) start_date_clean, max(end_date) end_date_clean
from tab group by CUSTOMER_ID, TYPE)
select tab.*, start_date_clean, end_date_clean
from tab join clean on tab.CUSTOMER_ID = clean.CUSTOMER_ID and tab.TYPE = clean.TYPE
where start_date != start_date_clean or end_date != end_date_clean
;
Этот запросвернет все строки, которые будут обработаны, т. е. либо начальная, либо конечная дата не верны.
Если это число большое - следуйте указаниям другого ответа - скопируйте таблицу и замените исходную таблицу наcopy.
Если ** число маленькое *, выберите update
/ delete
:
update tab a
set a.START_DATE = (select max(b.START_DATE) from tab b where a.customer_id = b.customer_id and a.type = b.type),
a.END_DATE = (select max(b.END_DATE) from tab b where a.customer_id = b.customer_id and a.type = b.type)
where (a.customer_id, a.type) in
(
select tab.CUSTOMER_ID, tab.TYPE
from tab join
(select CUSTOMER_ID, TYPE, max(start_date) start_date_clean, max(end_date) end_date_clean
from tab group by CUSTOMER_ID, TYPE) clean
on tab.CUSTOMER_ID = clean.CUSTOMER_ID and tab.TYPE = clean.TYPE
where start_date != start_date_clean or end_date != end_date_clean);
Обновление во всех затронутых строках start
и end
дата для правильных значений.
пример
CUSTOMER_ID START_DATE END_DATE TYPE
----------- ------------------- ------------------- ----------
1 01-01-2013 00:00:00 01-01-2016 00:00:00 1
1 01-01-2012 00:00:00 01-01-2018 00:00:00 1
1 01-01-2010 00:00:00 01-01-2017 00:00:00 1
2 01-01-2010 00:00:00 01-01-2018 00:00:00 1
3 01-01-2010 00:00:00 01-01-2018 00:00:00 1
обновлен до
CUSTOMER_ID START_DATE END_DATE TYPE
----------- ------------------- ------------------- ----------
1 01-01-2013 00:00:00 01-01-2018 00:00:00 1
1 01-01-2013 00:00:00 01-01-2018 00:00:00 1
1 01-01-2013 00:00:00 01-01-2018 00:00:00 1
2 01-01-2010 00:00:00 01-01-2018 00:00:00 1
3 01-01-2010 00:00:00 01-01-2018 00:00:00 1
На следующем шаге дублированные строки должны быть удалены.Это делает следующее удаление: какой пользователь ROW_NUMBER
идентифицирует дубликаты:
delete from tab where rowid in
(select RID from (
select rowid rid,
row_number() over (partition by CUSTOMER_ID, TYPE order by null) rn
from tab)
where rn > 1)
;
Что вы видите - метод копирования brute force прост в запросах, но оставляет таблицу в автономном режимена некоторое время.Для его выполнения требуется вдвое больше места, и это займет некоторое время.
Подход update является более сложным, но обходится без окна обслуживания и выполняется быстро.