sql >> Database >  >> RDS >> Oracle

6 manieren om dubbele rijen in Oracle te selecteren

De volgende voorbeelden retourneren dubbele rijen uit een Oracle Database-tabel.

Voorbeeldgegevens

Stel dat we een tabel hebben met de volgende gegevens:

SELECT * FROM Pets;

Resultaat:

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

De eerste twee rijen zijn duplicaten, evenals de laatste drie rijen. In dit geval bevatten de dubbele rijen dubbele waarden in alle kolommen, inclusief de ID-kolom.

Optie 1

We kunnen de volgende query gebruiken om te zien hoeveel rijen duplicaten zijn:

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

Resultaat:

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

We hebben de rijen op alle kolommen gegroepeerd en het aantal rijen van elke groep geretourneerd. Elke rij met een telling groter dan 1 is een duplicaat.

We kunnen het sorteren op telling in aflopende volgorde, zodat de rijen met de meeste duplicaten eerst verschijnen:

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

Resultaat:

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

Optie 2

Als we alleen de dubbele rijen willen vermelden, kunnen we de HAVING . gebruiken clausule om alleen rijen te retourneren met een telling groter dan 1:

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

Resultaat:

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

Optie 3

Een andere optie is om de ROW_NUMBER() . te gebruiken vensterfunctie:

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

Resultaat:

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

De PARTITION BY clausule verdeelt de resultaatset geproduceerd door de FROM clausule in partities waarop de functie wordt toegepast. Wanneer we partities specificeren voor de resultatenset, zorgt elke partitie ervoor dat de nummering opnieuw begint (d.w.z. de nummering begint bij 1 voor de eerste rij in elke partitie).

Optie 4

We kunnen de bovenstaande query gebruiken als een algemene tabeluitdrukking:

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;

Resultaat:

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

Dit retourneert alleen de overtollige rijen van de overeenkomende duplicaten. Dus als er twee identieke rijen zijn, wordt er één geretourneerd. Als er drie identieke rijen zijn, worden er twee geretourneerd, enzovoort.

Optie 5

Aangezien onze tabel geen primaire sleutelkolom bevat, kunnen we profiteren van Oracle's rowid pseudokolom:

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

Resultaat:

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

Zoals dit werkt, heeft elke rij in een Oracle-database een rowid pseudokolom die het adres van de rij retourneert. De rowid is een unieke id voor rijen in de tabel, en gewoonlijk identificeert de waarde ervan op unieke wijze een rij in de database. Het is echter belangrijk op te merken dat rijen in verschillende tabellen die samen in hetzelfde cluster zijn opgeslagen, dezelfde rowid kunnen hebben. .

Een voordeel van het bovenstaande voorbeeld is dat we SELECT * . kunnen vervangen met DELETE om de tabel te ontdubbelen.

Optie 6

En tot slot, hier is nog een optie die de rowid . gebruikt pseudokolom:

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

Resultaat:

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

Hetzelfde resultaat als het vorige voorbeeld.

Net als bij het vorige voorbeeld kunnen we SELECT * . vervangen met DELETE om dubbele rijen uit de tabel te verwijderen.


  1. Intel Xeon schaalbare processors en SQL Server 2017

  2. Vertrouwen herstellen in een externe sleutelbeperking in SQL Server (T-SQL-voorbeelden)

  3. Hoe het Amazon RDS-hoofdgebruikerswachtwoord opnieuw in te stellen

  4. Voeg alle gegevens van een datagridview in één keer in de database in