Oracle
 sql >> Baza danych >  >> RDS >> Oracle

6 sposobów na usunięcie zduplikowanych wierszy, które mają klucz podstawowy w Oracle

Oto kilka opcji usuwania zduplikowanych wierszy z tabeli w Oracle Database, gdy te wiersze mają klucz podstawowy lub kolumnę unikatowego identyfikatora.

W takich przypadkach klucz podstawowy musi zostać zignorowany podczas porównywania zduplikowanych wierszy (ze względu na fakt, że klucze podstawowe mają unikalne wartości).

Przykładowe dane

Nasze przykłady wykorzystują następujące dane:

SELECT * FROM Dogs;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
2 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

Widzimy, że pierwsze dwa wiersze są duplikatami, podobnie jak ostatnie trzy wiersze.

Id psa kolumna zawiera unikalne wartości (ponieważ jest to klucz podstawowy tabeli), ale ignorujemy tę kolumnę podczas porównywania duplikatów. Często może się okazać, że będziesz musiał usunąć duplikaty tabel zawierających klucze podstawowe, dlatego poniższe przykłady mogą służyć właśnie do tego.

Opcja 1

Oto nasza pierwsza opcja usuwania duplikatów powyższej tabeli:

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

SELECT * FROM Dogs;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Wag Johnson

Duplikaty zostały usunięte (ale jeden wiersz każdego duplikatu pozostaje).

Alternatywnie możemy użyć MAX() funkcja zamiast MIN() funkcja do zmiany, które wiersze są usuwane.

Opcja 2

W tym przykładzie (i w poniższych przykładach) założymy, że tabela została przywrócona do swojego pierwotnego stanu (z duplikatami).

Oto kolejny przykład, który usuwa duplikat tabeli, a następnie zaznacza pozostałe wiersze:

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;

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
3 Huu Jones
4 kryza Robinson
7 Wag Johnson

Zauważ, że użyłem MAX() funkcja zamiast MIN() którego użyłem w poprzednim przykładzie. Widzimy wpływ, jaki ma to na operację usuwania duplikatów. Usunął różne wiersze z tabeli.

Opcja 3

Oto opcja, która nie wymaga użycia MIN() lub 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;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Wag Johnson

Opcja 4

Oto kolejna opcja:

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

SELECT * FROM Dogs;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Wag Johnson

Opcja 5

Każdy wiersz w Oracle ma rowid pseudokolumna, która zwraca adres wiersza. rowid jest unikalnym identyfikatorem wierszy w tabeli i zwykle jego wartość jednoznacznie identyfikuje wiersz w bazie danych (chociaż należy pamiętać, że wiersze w różnych tabelach, które są przechowywane razem w tym samym klastrze, mogą mieć ten sam rowid ).

Możemy zatem użyć rowid w naszym zapytaniu zamiast DogId kolumna:

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;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Wag Johnson

Chociaż ten przykład może wydawać się nieco zbędny, biorąc pod uwagę, że mamy już kolumnę klucza podstawowego, mogą wystąpić sytuacje, w których wolisz użyć rowid . rowid może być przydatne, jeśli z jakiegoś powodu nie możesz użyć kolumny klucza podstawowego lub jeśli tabela nie ma klucza podstawowego. Ponadto dokumentacja Oracle wspomina, że ​​rowid wartości to najszybszy sposób na dostęp do pojedynczego wiersza.

Opcja 6

A oto drugi przykład, ale z rowid zamiast klucza podstawowego:

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

SELECT * FROM Dogs;

Wynik:

DOGI FIRSTNAME NAZWISKO
1 Kora Kowalski
3 Huu Jones
4 kryza Robinson
5 Machać Johnson

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zwróć krótką nazwę miesiąca z daty w Oracle

  2. Tworzenie listy wartości oddzielonych przecinkami w instrukcji Oracle SQL

  3. Czy zakleszczenie może wystąpić przy tej samej metodzie dostępu?

  4. Jaka jest poprawna składnia adresu URL JDBC w przypadku korzystania z portfeli Oracle?

  5. Jak uzyskać dostęp do bazy danych Oracle w VirtualBox z hosta (Windows)