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

11 sposobów na znalezienie zduplikowanych wierszy, które mają klucz podstawowy w Oracle

Oto jedenaście opcji zwracania zduplikowanych wierszy w Oracle Database, gdy te wiersze mają klucz podstawowy lub inną kolumnę unikatowego identyfikatora i chcesz ją zignorować.

Przykładowe dane

W naszych przykładach użyjemy następujących danych:

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

Pierwsze dwa wiersze są duplikatami, a ostatnie trzy wiersze są duplikatami. Zduplikowane wiersze mają dokładnie te same wartości we wszystkich kolumnach z wyjątkiem ich kolumny klucza podstawowego/unikalnego identyfikatora.

Kolumna klucza podstawowego zapewnia, że ​​nie ma zduplikowanych wierszy, co jest dobrą praktyką w systemach RDBMS, ponieważ klucze podstawowe pomagają wymusić integralność danych. Jednak fakt, że klucze podstawowe zawierają unikatowe wartości, oznacza, że ​​musimy zignorować tę kolumnę podczas wyszukiwania duplikatów.

W naszej tabeli powyżej kolumna klucza podstawowego jest liczbą rosnącą, a jej wartość nie ma znaczenia i nie jest istotna. Możemy zatem zignorować dane tej kolumny podczas wyszukiwania duplikatów.

Opcja 1

Oto nasza pierwsza opcja zwracania duplikatów:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
ORDER BY Count DESC;

Wynik:

FIRSTNAME NAZWISKO LICZBA
Wag Johnson 3
Kora Kowalski 2
kryza Robinson 1
Hał Jones 1

Tutaj skonstruowaliśmy nasze zapytanie za pomocą GROUP BY tak, aby dane wyjściowe były pogrupowane według odpowiednich kolumn. Użyliśmy również COUNT() funkcja zwracająca liczbę identycznych wierszy. Uporządkowaliśmy je według liczby w porządku malejącym, aby duplikaty pojawiły się jako pierwsze.

Wynik mówi nam, że istnieją trzy wiersze zawierające Wag Johnson i dwa wiersze zawierające Bark Smith. Są to duplikaty (lub trzy egzemplarze w przypadku Wag Johnson). Pozostałe dwa wiersze nie mają żadnych duplikatów.

Opcja 2

Możemy dodać HAVING klauzula do naszego poprzedniego przykładu, aby wykluczyć nieduplikaty z danych wyjściowych:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1
ORDER BY Count DESC;

Wynik:

FIRSTNAME NAZWISKO LICZBA
Wag Johnson 3
Kora Kowalski 2

Opcja 3

Możemy również sprawdzić duplikaty w połączonych kolumnach. W tym przypadku używamy DISTINCT słowa kluczowego, aby uzyskać różne wartości, a następnie użyj COUNT() funkcja zwracająca liczbę:

SELECT
    DISTINCT FirstName || ' ' || LastName AS DogName,
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName || ' ' || LastName
ORDER BY Count DESC;

Wynik:

NAZWA PSA LICZBA
Wag Johnson 3
Kora Kowal 2
Ruff Robinson 1
Hau Jones 1

Opcja 4

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 ).

W każdym razie możemy skonstruować zapytanie, które używa rowid jeśli chcemy:

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

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
6 Wag Johnson
7 Wag Johnson

Moglibyśmy zastąpić SELECT * z USUŃ aby wykonać operację usuwania duplikatów na stole.

Zauważ, że mogliśmy użyć DogId kolumna (nasz klucz podstawowy) zamiast rowid gdybyśmy chcieli. To powiedziawszy, 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.

Opcja 5

Oto kolejne zapytanie, które używa rowid :

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

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
6 Wag Johnson
7 Wag Johnson

Podobnie jak w poprzednim przykładzie, możemy zastąpić SELECT * z USUŃ aby usunąć zduplikowane wiersze.

Opcja 6

Dwa rowid powyższe opcje są świetne, jeśli musisz całkowicie zignorować klucz podstawowy w zapytaniu (lub jeśli w ogóle nie masz kolumny klucza podstawowego). Jednak jak wspomniano, nadal istnieje możliwość zastąpienia rowid z kolumną klucza podstawowego – w naszym przypadku DogId kolumna:

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

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
6 Wag Johnson
7 Wag Johnson

Opcja 7

A oto inne zapytanie z rowid zastąpione przez DogId kolumna:

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

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
6 Wag Johnson
7 Wag Johnson

Opcja 8

Innym sposobem na znalezienie duplikatów jest użycie ROW_NUMBER() funkcja okna:

SELECT 
    DogId,
    FirstName,
    LastName,
    ROW_NUMBER() OVER ( 
        PARTITION BY FirstName, LastName 
        ORDER BY FirstName, LastName
        ) AS row_num
FROM Dogs;

Wynik:

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

Korzystanie z PARTYCJI klauzula powoduje dodanie nowej kolumny z numerem wiersza, który zwiększa się za każdym razem, gdy pojawia się duplikat, ale resetuje się ponownie, gdy istnieje unikalny wiersz.

W tym przypadku nie grupujemy wyników, co oznacza, że ​​możemy zobaczyć każdy zduplikowany wiersz, w tym jego kolumnę z unikalnym identyfikatorem.

Opcja 9

Możemy również użyć poprzedniego przykładu jako wspólnego wyrażenia tabelowego w większym zapytaniu:

WITH cte AS 
    (
        SELECT 
            DogId,
            FirstName,
            LastName,
            ROW_NUMBER() OVER ( 
                PARTITION BY FirstName, LastName 
                ORDER BY FirstName, LastName
                ) AS row_num
        FROM Dogs
    )
SELECT * FROM cte WHERE row_num <> 1;

Wynik:

DOGI FIRSTNAME NAZWISKO ROW_NUM
2 Kora Kowalski 2
5 Wag Johnson 2
6 Wag Johnson 3

To zapytanie wyklucza nieduplikaty z danych wyjściowych i wyklucza jeden wiersz każdego duplikatu z danych wyjściowych.

Opcja 10

Oto inny sposób na uzyskanie tego samego wyniku, co w poprzednim przykładzie:

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

Wynik:

DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski
6 Wag Johnson
7 Wag Johnson

W tym przykładzie użyto MINUS Oracle operator, który zwraca tylko unikalne wiersze zwrócone przez pierwsze zapytanie, ale nie przez drugie.

MINUS operator jest podobny do EXCEPT operatora w innych DBMS, takich jak SQL Server, MariaDB, PostgreSQL i SQLite.

Opcja 11

Oto kolejna opcja wyboru duplikatów z naszej tabeli:

SELECT * 
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
);

Wynik:

DOGI FIRSTNAME NAZWISKO DOGI FIRSTNAME NAZWISKO
2 Kora Kowalski 1 Kora Kowalski
7 Wag Johnson 5 Wag Johnson
7 Wag Johnson 6 Wag 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. Jak uzyskać skrypt tabeli w Oracle SQL Developer?

  2. Erlang i jego zużycie pamięci sterty

  3. Program PL/SQL do drukowania danych pracowników

  4. wyrocznia varchar na numer

  5. Wyodrębnianie całkowitej liczby sekund z typu danych interwału