sql >> Database >  >> RDS >> SQLite

6 manieren om dubbele rijen in SQLite te selecteren

De volgende query's kunnen worden gebruikt om dubbele rijen in SQLite te retourneren.

Hier bevatten de dubbele rijen dubbele waarden in alle kolommen, inclusief de ID-kolom.

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. Dat komt omdat alle drie de kolommen dezelfde waarden bevatten in elke dubbele rij.

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    

Hier hebben we de rijen gegroepeerd op alle kolommen en het aantal rijen van elke groep geretourneerd. Dit vertelt ons of een rij uniek is (met een telling van 1) of een duplicaat (met een telling groter dan 1).

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 hebben, 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 PetId;

Resultaat:

PetId  PetName  PetType  Count
-----  -------  -------  -----
1      Wag      Dog      2    
4      Bark     Dog      3    

Optie 3

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

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

Resultaat:

PetId  PetName  PetType  Row_Number
-----  -------  -------  ----------
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 
            *, 
            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.

Deze query kan handig zijn om te laten zien hoeveel rijen er uit de tabel worden verwijderd bij een ontdubbelingsbewerking. In sommige andere DBMS'en (tenminste in SQL Server), kunnen we de laatste SELECT * . vervangen met DELETE om de dubbele rijen uit de tabel te verwijderen. Maar SQLite laat ons de CTE niet zo updaten.

Gelukkig kunnen de volgende twee opties worden gewijzigd om een ​​verwijdering uit te voeren.

Optie 5

We kunnen profiteren van SQLite's rowid :

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    

Hoe werkt dit? Standaard heeft elke rij in SQLite een speciale kolom, meestal de rowid , die die rij in de tabel op unieke wijze identificeert. Dit kan indien nodig worden verwijderd, maar tenzij het expliciet is verwijderd, kunt u het gebruiken in uw zoekopdrachten.

Optie 6

En tot slot, hier is nog een optie die gebruikmaakt van SQLite's rowid :

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    

  1. Groeperen op gegevensintervallen

  2. Datumparameter toevoegen aan Oracle-query

  3. SQL-query om kolomwaarden te krijgen die overeenkomen met de MAX-waarde van een andere kolom?

  4. Wat is er nieuw in Access 2016? Is het de moeite waard om te upgraden?