sql >> Databáze >  >> RDS >> Oracle

6 způsobů, jak odstranit duplicitní řádky, které mají primární klíč v Oracle

Zde je několik možností pro odstranění duplicitních řádků z tabulky v databázi Oracle, pokud tyto řádky mají sloupec primárního klíče nebo jedinečného identifikátoru.

V takových případech musí být primární klíč při porovnávání duplicitních řádků ignorován (kvůli skutečnosti, že primární klíče obsahují jedinečné hodnoty).

Ukázková data

Naše příklady používají následující data:

SELECT * FROM Dogs;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
2 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

Vidíme, že první dva řádky jsou duplikáty, stejně jako poslední tři řádky.

DogId sloupec obsahuje jedinečné hodnoty (protože je to primární klíč tabulky), ale při porovnávání duplikátů tento sloupec ignorujeme. Možná se často přistihnete, že potřebujete deduplikovat tabulky, které obsahují primární klíče, a proto k tomu lze použít následující příklady.

Možnost 1

Zde je naše první možnost, jak odstranit duplikáty výše uvedené tabulky:

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

SELECT * FROM Dogs;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson

Duplikáty byly odstraněny (ale jeden řádek z každého duplikátu zůstal).

Alternativně můžeme použít MAX() místo funkce MIN() funkce pro změnu, které řádky se mají odstranit.

Možnost 2

V tomto příkladu (a v následujících příkladech) budeme předpokládat, že tabulka byla obnovena do původního stavu (s duplikáty).

Zde je další příklad, který deduplikuje tabulku a poté vybere zbývající řádky:

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;

Výsledek:

DOGID FIRSTNAME LASTNAME
2 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
7 Wag Johnson

Všimněte si, že jsem použil MAX() funkce namísto MIN() který jsem použil v předchozím příkladu. Vidíme, jaký to má vliv na operaci odstranění duplikace. Z tabulky byly odstraněny různé řádky.

Možnost 3

Zde je možnost, která nevyžaduje použití MIN() nebo 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;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson

Možnost 4

Zde je další možnost:

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

SELECT * FROM Dogs;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson

Možnost 5

Každý řádek v Oracle má rowid pseudosloupec, který vrací adresu řádku. rowid je jedinečný identifikátor pro řádky v tabulce a jeho hodnota obvykle jednoznačně identifikuje řádek v databázi (ačkoli je důležité si uvědomit, že řádky v různých tabulkách, které jsou uloženy společně ve stejném clusteru, mohou mít stejný rowid ).

Můžeme tedy použít rowid v našem dotazu namísto DogId sloupec:

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;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson

I když se tento příklad může zdát poněkud nadbytečný, protože již máme sloupec primárního klíče, mohou nastat případy, kdy upřednostňujete použití rowid . rowid může být užitečné, pokud z nějakého důvodu nemůžete použít sloupec primárního klíče nebo pokud tabulka primární klíč nemá. Dokumentace Oracle také uvádí, že rowid hodnoty jsou nejrychlejším způsobem přístupu k jednomu řádku.

Možnost 6

A zde je další příklad, ale s rowid místo primárního klíče:

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

SELECT * FROM Dogs;

Výsledek:

DOGID FIRSTNAME LASTNAME
1 Kůra Smith
3 Fuj Jones
4 Ruff Robinson
5 Wag Johnson

  1. Mysql počítá instance podřetězce a poté seřaďte podle

  2. ORA-01111 v MRP v databázi fyzického pohotovostního režimu

  3. Jak vkládat data přímo z Excelu do databáze Oracle

  4. Skryté vlastnosti PostgreSQL