Если у вас нет «уникального идентификатора» для строк (в таблицах DB1 и DB2), вы можете вместо этого использовать ROWID .Найдите ROWID идентификаторов и удалите их.
Первые шаги: {1} использовать ROW_NUMBER () над (...) для "маркировки" уникальных комбинаций c1 / c2 {2} найти ROWIDs DB2{3} используйте OUTER JOIN для фильтрации.
select DB1.c1, DB1.c2, DB1.rn1_
, DB2.rowid_, DB2.c1, DB2.c2, DB2.rn2_
from (
select c1, c2
, row_number() over ( partition by c1, c2 order by c1 ) rn1_ -- {1}
from db1
) DB1 right join ( -- {3}
select rowid as rowid_, c1, c2 -- {2}
, row_number() over ( partition by c1, c2 order by c1 ) rn2_ -- {1}
from db2
) DB2 on DB1.c1 = DB2.c1 and DB1.c2 = DB2.c2 and DB1.rn1_ = DB2.rn2_
where DB1.c1 is null and DB1.c2 is null ;
-- result
C1 C2 RN1_ ROWID_ C1 C2 RN2_
AAAT6DAAMAAACNzAAC A 23-SEP-19 3
AAAT6DAAMAAACNzAAD A 23-SEP-19 4
AAAT6DAAMAAACNzAAF B 22-SEP-19 2
Resultset того же запроса (как указано выше) с предложением WHERE "закомментировано":
C1 C2 RN1_ ROWID_ C1 C2 RN2_
A 23-SEP-19 1 AAAT6DAAMAAACNzAAA A 23-SEP-19 1
A 23-SEP-19 2 AAAT6DAAMAAACNzAAB A 23-SEP-19 2
B 22-SEP-19 1 AAAT6DAAMAAACNzAAE B 22-SEP-19 1
AAAT6DAAMAAACNzAAC A 23-SEP-19 3
AAAT6DAAMAAACNzAAD A 23-SEP-19 4
AAAT6DAAMAAACNzAAF B 22-SEP-19 2
Если это выглядитхорошо, затем ВЫБЕРИТЕ значения DB2.rowid_ (только) и используйте их в предложении WHERE для DELETE:
SQL> delete db2
2 where rowid in (
3 select DB2.rowid_ -- select the rowid_ ONLY!
4 from (
5 select c1, c2
6 , row_number() over ( partition by c1, c2 order by c1 ) rn1_
7 from db1
8 ) DB1 right join (
9 select rowid as rowid_, c1, c2
10 , row_number() over ( partition by c1, c2 order by c1 ) rn2_
11 from db2
12 ) DB2 on DB1.c1 = DB2.c1 and DB1.c2 = DB2.c2 and DB1.rn1_ = DB2.rn2_
13 where DB1.c1 is null and DB1.c2 is null
14 ) ;
3 rows deleted.
Таблица DB2 теперь содержит:
SQL> select * from DB2 ;
C1 C2
A 23-SEP-19
A 23-SEP-19
B 22-SEP-19
updates
Чтобы избежать трудностей с NULL, используйте этот модифицированный оператор DELETE:
delete db2
where rowid in (
select DB2.rowid_
from (
select to_char( c1 ) || to_char( c2 )
|| to_char( row_number() over ( partition by c1, c2 order by c1 ) ) concat1
from db1
) DB1
right join (
select rowid as rowid_
, to_char( c1 ) || to_char( c2 )
|| to_char( row_number() over ( partition by c1, c2 order by c1 ) ) concat2
from db2
) DB2 on DB1.concat1 = DB2.concat2
where DB1.concat1 is null
) ;
Протестировано с Oracle 18c и 19c - см. пример @ lifeql .