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

6 sposobów na wybranie zduplikowanych wierszy w Oracle

Poniższe przykłady zwracają zduplikowane wiersze z tabeli bazy danych Oracle.

Przykładowe dane

Załóżmy, że mamy tabelę z następującymi danymi:

SELECT * FROM Pets;

Wynik:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
1      Wag      Dog    
2      Scratch  Cat    
3      Tweet    Bird   
4      Bark     Dog    
4      Bark     Dog    
4      Bark     Dog    

Pierwsze dwa wiersze są duplikatami, podobnie jak ostatnie trzy wiersze. W takim przypadku zduplikowane wiersze zawierają zduplikowane wartości we wszystkich kolumnach, w tym w kolumnie ID.

Opcja 1

Możemy użyć następującego zapytania, aby zobaczyć, ile wierszy jest duplikatami:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Wynik:

PETID	PETNAME	PETTYPE	Count
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1
4	Bark	Dog	3

Pogrupowaliśmy wiersze według wszystkich kolumn i zwróciliśmy liczbę wierszy każdej grupy. Każdy wiersz z liczbą większą niż 1 jest duplikatem.

Możemy uporządkować to według liczby w porządku malejącym, tak aby wiersze z największą liczbą duplikatów pojawiły się jako pierwsze:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC;

Wynik:

PETID	PETNAME	PETTYPE	Count
4	Bark	Dog	3
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1

Opcja 2

Jeśli chcemy wyświetlić tylko zduplikowane wiersze, możemy użyć HAVING klauzula zwracająca tylko wiersze o liczbie większej niż 1:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC;

Wynik:

PETID	PETNAME	PETTYPE	Count
4	Bark	Dog	3
1	Wag	Dog	2

Opcja 3

Inną opcją jest użycie ROW_NUMBER() funkcja okna:

SELECT 
    PetId,
    PetName,
    PetType,
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS rn
FROM Pets;

Wynik:

PETID	PETNAME	PETTYPE	RN
1	Wag	Dog	1
1	Wag	Dog	2
2	Scratch	Cat	1
3	Tweet	Bird	1
4	Bark	Dog	1
4	Bark	Dog	2
4	Bark	Dog	3

PARTITION BY klauzula dzieli zbiór wyników utworzony przez FROM klauzuli na przegrody, do których funkcja jest stosowana. Kiedy określamy partycje dla zestawu wyników, każda partycja powoduje, że numeracja zaczyna się od nowa (tj. numeracja rozpocznie się od 1 dla pierwszego wiersza w każdej partycji).

Opcja 4

Możemy użyć powyższego zapytania jako wspólnego wyrażenia tabelowego:

WITH cte AS 
    (
        SELECT 
            PetId,
            PetName,
            PetType,
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
SELECT * FROM cte WHERE Row_Number <> 1;

Wynik:

PETID	PETNAME	PETTYPE	ROW_NUMBER
1	Wag	Dog	2
4	Bark	Dog	2
4	Bark	Dog	3

Zwraca to tylko nadmiarowe wiersze z pasujących duplikatów. Więc jeśli są dwa identyczne wiersze, zwraca jeden z nich. Jeśli są trzy identyczne wiersze, zwraca dwa i tak dalej.

Opcja 5

Biorąc pod uwagę, że nasza tabela nie zawiera kolumny klucza podstawowego, możemy skorzystać z rowid firmy Oracle pseudokolumna:

SELECT * FROM Pets
WHERE EXISTS (
  SELECT 1 FROM Pets p2 
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
  AND Pets.rowid > p2.rowid
);

Wynik:

PETID	PETNAME	PETTYPE
1	Wag	Dog
4	Bark	Dog
4	Bark	Dog

Działa to tak, że każdy wiersz w bazie danych 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. Należy jednak pamiętać, że wiersze w różnych tabelach, które są przechowywane razem w tym samym klastrze, mogą mieć ten sam rowid .

Jedną z zalet powyższego przykładu jest to, że możemy zastąpić SELECT * z DELETE w celu usunięcia duplikatów tabeli.

Opcja 6

I na koniec, oto kolejna opcja, która używa rowid pseudokolumna:

SELECT * FROM Pets
WHERE rowid > (
  SELECT MIN(rowid) FROM Pets p2  
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
);

Wynik:

PETID	PETNAME	PETTYPE
1	Wag	Dog
4	Bark	Dog
4	Bark	Dog

Taki sam wynik jak w poprzednim przykładzie.

Podobnie jak w poprzednim przykładzie, możemy zastąpić SELECT * z DELETE w celu usunięcia zduplikowanych wierszy z tabeli.


  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 połączyć wiele wierszy w jeden w Oracle bez tworzenia procedury składowanej?

  2. Jak wygenerować pakiet API tabeli w Oracle SQL Developer?

  3. Jak mogę zobaczyć zapytania, które są wykonywane w Oracle?

  4. pobrać parametr z procedury składowanej?

  5. Funkcja pliku kontrolnego migawki z RMAN i ORA-00245