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

6 måder at slette duplikerede rækker, der har en primær nøgle i Oracle

Her er nogle muligheder for at slette duplikerede rækker fra en tabel i Oracle Database, når disse rækker har en primær nøgle eller en unik identifikatorkolonne.

I sådanne tilfælde skal den primære nøgle ignoreres ved sammenligning af duplikerede rækker (på grund af det faktum, at primærnøgler har unikke værdier).

Eksempeldata

Vores eksempler bruger følgende data:

SELECT * FROM Dogs;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
2 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

Vi kan se, at de første to rækker er dubletter, ligesom de sidste tre rækker.

DogId kolonne indeholder unikke værdier (fordi det er tabellens primære nøgle), men vi ignorerer den kolonne, når vi sammenligner dubletter. Du kan ofte opleve, at du har brug for at de-dupere tabeller, der indeholder primærnøgler, og derfor kan følgende eksempler bruges til netop det.

Valgmulighed 1

Her er vores første mulighed for at de-dupere ovenstående tabel:

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

SELECT * FROM Dogs;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson

Dubletterne er blevet fjernet (men der er en række tilbage af hvert duplikat).

Vi kan alternativt bruge MAX() funktion i stedet for MIN() funktion for at ændre, hvilke rækker der slettes.

Valgmulighed 2

I dette eksempel (og de følgende eksempler) antager vi, at tabellen er blevet gendannet til sin oprindelige tilstand (med dubletterne).

Her er et andet eksempel, der de-duperer tabellen og derefter vælger de resterende rækker:

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;

Resultat:

DOGID FIRSTNAME Efternavn
2 Smith
3 Wuf Jones
4 Ruff Robinson
7 Wag Johnson

Bemærk, at jeg brugte MAX() funktion i stedet for MIN() som jeg brugte i det forrige eksempel. Vi kan se, hvilken indflydelse dette har på de-duping-operationen. Det slettede forskellige rækker fra tabellen.

Valgmulighed 3

Her er en mulighed, der ikke kræver brug af MIN() eller 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;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson

Valgmulighed 4

Her er en anden mulighed:

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

SELECT * FROM Dogs;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson

Valgmulighed 5

Hver række i Oracle har en rowid pseudokolonne, der returnerer adressen på rækken. rovid er en unik identifikator for rækker i tabellen, og normalt identificerer dens værdi entydigt en række i databasen (selvom det er vigtigt at bemærke, at rækker i forskellige tabeller, der er gemt sammen i den samme klynge, kan have den samme række kode> ).

Vi kan derfor bruge rovid i vores forespørgsel i stedet for DogId kolonne:

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;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson

Selvom dette eksempel kan virke lidt overflødigt, da vi allerede har en primær nøglekolonne, kan der være tilfælde, hvor du foretrækker at bruge rovid . rovid kan være nyttigt, hvis du af en eller anden grund ikke kan bruge den primære nøglekolonne, eller hvis tabellen ikke har en primærnøgle. Oracles dokumentation nævner også, at rowid værdier er den hurtigste måde at få adgang til en enkelt række på.

Valgmulighed 6

Og her er det andet eksempel, men med rovid i stedet for den primære nøgle:

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

SELECT * FROM Dogs;

Resultat:

DOGID FIRSTNAME Efternavn
1 Smith
3 Wuf Jones
4 Ruff Robinson
5 Wag Johnson

  1. Et par små problemer med Hekaton prøver

  2. Hvordan forespørger jeg alle rækker inden for en radius på 5 mil fra mine koordinater?

  3. Automatisering af den tabelformede modelbehandling af SSAS-databaser i SQL Server

  4. Meget langsom opstart af Spring Boot-applikation