Сложно на этой самой посгре...
Oracle
Код: Выделить всё
-- Лентяйка для генерации запроса по таблице, где многакалонкафф
-- WARN: поля LOB, long [raw], объекты и т.п. в любом случае потребуют особого
-- внимания, потому фильтровать не стал - данные целее будут.
select q'[delete dept_dubl where (rowid, 1) in
(select rowid , lag(1) over(partition by ]'
|| listagg(column_name,',')
|| q'[ order by 1) k
from dept_dubl)]'
stmnt
from all_tab_cols
where table_name = upper('dept_dubl')
group by table_name
/
Код: Выделить всё
begin
for i in (<текст лентяйки>) loop
execute immediate i.stmnt;
end loop;
end;
/
Код: Выделить всё
SQL>
delete dept_dubl where (rowid, 1) in
(select rowid, lag(1) over(partition by DEPTNO,DNAME,LOC order by 1) k
from dept_dubl)
/
6 rows deleted
SQL>
select * from dept_dubl t
/
DEPTNO DNAME LOC
------ -------------------------------------------------------- ----------------------------------------------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
rollback
/
Rollback complete
Код: Выделить всё
SQL>
delete dept_dubl
where rowid NOT in
(select min(rowid)
from dept_dubl t
group by DEPTNO,DNAME,LOC)
/
6 rows deleted
SQL>
select * from dept_dubl t
/
DEPTNO DNAME LOC
------ -------------------------------------------------------- ----------------------------------------------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
Если табличка совсем большая, секционированная, лежит на кластере, содержит особые типы данных и т.п.,
то игрушки следует оставить детям и решать проблему всерьёз и комплексно.
Как минимум:
- определить и изолировать/пофиксить источник дублей
- по возможности прикрыть данные от появления новых дублей, НАПРИМЕР (см. оговорки выше, которые потребуют учета)
Код: Выделить всё
-- создаём НЕуникальный индекс
SQL> create index dept_dubl$dedup on dept_dubl(DEPTNO,DNAME,LOC) online
2 /
Index created
-- и вешаем на него UK (можно и PK, если ситуация позволяет)
SQL> alter table dept_dubl add constraint dept_dubl#dedup primary key (DEPTNO,DNAME,LOC) using index dept_dubl$dedup [color=#FF0000]NOVALIDATE[/color]
2 /
Table altered
-- Как оно?
SQL> insert into dept_dubl select * from dept_dubl;
insert into dept_dubl select * from dept_dubl
ORA-00001: unique constraint (GIS_MRG.DEPT_DUBL#DEDUP) violated
- с помощью constraint предотвратит появление новых дублей
- поможет ловкому ораклоиду избежать жирных сортировок при поиске и устранении дублей, съэкономив кучу времени
Ну а дальше проводить дедубликацию наиболее уместным в конкретной ситуации способом (коих довольно много).
ЗЫ: помянутый в топике "универсальный" способ, да еще опубликованный в какой-то книжке, суть игрушка даже не детсадовского - ясельного возраста, потому что в детском саду уже умеют пользоваться IDE, которые сами подставляют все атрибуты таблички, а взрослые дяди-счетоводы даже умеют генерировать код по словарю.