sql >> Databasteknik >  >> RDS >> Oracle

Ta bort poster från en tabell kopplad till en annan tabell SQL

Du behöver inte använda OUTER JOIN förutom kontrollen hur många rader som kommer resp. kommer inte raderas.

Ett exempel på en sådan fråga se nedan (jag använder genererade testdata som tillhandahålls i slutet av svaret)

with del as (
select delta.id, delta.version,
decode(big.id,null,0,1) is_deleted
from delta
left outer join big 
on delta.id = big.id and delta.version = big.version
)
select is_deleted, count(*) cnt, max(id||'.'||version) eg_id_vers
from del
group by is_deleted;

IS_DELETED        CNT  EG_ID_VERS                                                                   
---------- ---------- ----------
         1      20000 99995.0   
         0         20 100100.0   

Med din datastorlek bör du använda en HASH JOIN med full table scan på båda borden för att få acceptabel prestanda.

Det finns i princip två alternativ hur man gör DELETE

Uppdaterbar anslutningsvy

Observera att i det här fallet måste ditt lilla bord ha ett unikt index på ID, VERSION (eller en primärnyckel)

create unique index delta_idx on delta(id,version);

Tvärtemot borde BIG-tabellen inte ha en sådan begränsning . Detta är viktigt eftersom det tydligt indikerar att din BIG-tabell är den enda nyckelbevarande tabellen i sammanfogningsvyn.

Lägg enkelt en koppling till den lilla tabellen kan inte duplicera rader från det stora bordet på grund av den unika kontraint

Se här mer information om Uppdatera en Join Views

delete from 
(
select delta.id, delta.version, big.id big_id, big.version
from big 
join delta 
on delta.id = big.id and delta.version = big.version
)

delete ovan tar bort rader från BIG tabell eftersom detta är den enda nyckelbevarande tabellen (se diskussionen ovan)

Denna DML leder till en HASH JOIN

Ta bort med EXISTS

Om din lilla tabell inte har någon primärnyckel (dvs. den kan innehålla dubblerade rader med samma ID and VERSION ) måste du återgång till lösningen som föreslås i annat svar .

DELETE FROM big 
    WHERE EXISTS (SELECT null
                  FROM delta
                  WHERE delta.id = big.id and delta.version = big.version
                 ) 

Inga index krävs och du bör förvänta dig en exekveringsplan med HASH JOIN RIGHT SEMI , vilket betyder att båda tillvägagångssätten inte är riktigt olika.

Exempeldata för test

create table big as
select 
trunc(rownum/10) id, mod(rownum,10) version,
lpad('x',10,'Y') pad
from dual connect by level <= 1000000;

/* the DELTA table has 50 times less rows,
allow some rows out of range of the BIG table - those rows will not be deleted **/
drop table delta;
create table delta as
select 
trunc(rownum*50/10) id, mod(rownum*50,10) version
from dual connect by level <= 1001000/50;

create unique index delta_idx on delta(id,version);


  1. Hur skapar man en komplex virtuell kolumn i en vältalig modell?

  2. MYSQL INNER JOIN med möjliga tomma fält

  3. Hämta aktuella loggade användardetaljer för tabellen jhi_persistenet_audit_event

  4. Frågor om typer i MySQL