Oracle
 sql >> Database >  >> RDS >> Oracle

6 modi per eliminare le righe duplicate che hanno una chiave primaria in Oracle

Di seguito sono riportate alcune opzioni per eliminare le righe duplicate da una tabella in Oracle Database quando tali righe hanno una chiave primaria o una colonna identificatore univoco.

In questi casi, la chiave primaria deve essere ignorata quando si confrontano le righe duplicate (a causa del fatto che le chiavi primarie contengono valori univoci).

Dati campione

I nostri esempi utilizzano i seguenti dati:

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
2 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

Possiamo vedere che le prime due righe sono duplicate, così come le ultime tre righe.

Il DogId la colonna contiene valori univoci (perché è la chiave primaria della tabella), ma stiamo ignorando quella colonna quando confrontiamo i duplicati. Potresti trovarti spesso a dover deduplicare le tabelle che contengono chiavi primarie, quindi i seguenti esempi possono essere utilizzati proprio per questo.

Opzione 1

Ecco la nostra prima opzione per deduplicare la tabella sopra:

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    MINUS SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson

I duplicati sono stati rimossi (ma rimane una riga di ogni duplicato).

In alternativa possiamo usare il MAX() funzione invece di MIN() funzione per modificare le righe da eliminare.

Opzione 2

In questo esempio (e negli esempi seguenti) assumeremo che la tabella sia stata ripristinata allo stato originale (con i duplicati).

Ecco un altro esempio che deduplica la tabella e quindi seleziona le righe rimanenti:

DELETE FROM Dogs WHERE DogId IN (
    SELECT d2.DogId 
    FROM Dogs d1, Dogs d2 
    WHERE d1.FirstName = d2.FirstName 
    AND d1.LastName = d2.LastName 
    AND d1.DogId <> d2.DogId 
    AND d1.DogId=( 
        SELECT MAX(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
2 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
7 Wag Johnson

Nota che ho usato MAX() funzione invece di MIN() che ho usato nell'esempio precedente. Possiamo vedere l'effetto che questo ha sull'operazione di de-duping. Ha cancellato diverse righe dalla tabella.

Opzione 3

Ecco un'opzione che non richiede l'uso di MIN() o MAX() :

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
);

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson

Opzione 4

Ecco un'altra opzione:

DELETE FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson

Opzione 5

Ogni riga in Oracle ha un rowid pseudocolonna che restituisce l'indirizzo della riga. Il rowid è un identificatore univoco per le righe nella tabella e di solito il suo valore identifica in modo univoco una riga nel database (sebbene sia importante notare che righe in tabelle diverse che sono archiviate insieme nello stesso cluster possono avere lo stesso rowid ).

Possiamo quindi utilizzare il rowid nella nostra query invece di DogId colonna:

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
);

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson

Sebbene questo esempio possa sembrare leggermente superfluo, dato che abbiamo già una colonna di chiave primaria, potrebbero esserci casi in cui preferisci utilizzare il rowid . Il rowid può essere utile se per qualche motivo non è possibile utilizzare la colonna della chiave primaria o se la tabella non dispone di una chiave primaria. Inoltre, la documentazione di Oracle menziona che rowid i valori sono il modo più veloce per accedere a una singola riga.

Opzione 6

Ed ecco l'altro esempio, ma con rowid invece della chiave primaria:

DELETE FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Risultato:

DOGID COGNOME COGNOME
1 Corteccia Fabio
3 Trama Jones
4 Ruff Robinson
5 Wag Johnson