Følgende forespørgsler kan bruges til at returnere duplikerede rækker i SQLite.
Her indeholder dubletrækkerne duplikerede værdier på tværs af alle kolonner, inklusive ID-kolonnen.
Eksempeldata
Antag, at vi har en tabel med følgende data:
VÆLG * FRA kæledyr;
Resultat:
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 første to rækker er dubletter, ligesom de sidste tre rækker. Det skyldes, at alle tre kolonner indeholder de samme værdier i hver dubletrække.
Valgmulighed 1
Vi kan bruge følgende forespørgsel til at se, hvor mange rækker der er dubletter:
VÆLG PetId, PetName, PetType, COUNT(*) AS "Count"FRA PetsGROUP BY PetId, PetName, PetTypeORDER BY PetId;
Resultat:
PetId PetName PetType Antal----- ------- ------- -----1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Fugl 1 4 Bark Dog 3
Her grupperede vi rækkerne efter alle kolonner og returnerede rækkeantallet for hver gruppe. Dette fortæller os, om en række er unik (med et antal på 1) eller en dublet (med et antal større end 1).
Vi kan bestille det efter antal i faldende rækkefølge, så rækkerne med flest dubletter vises først:
VÆLG PetId, PetName, PetType, COUNT(*) AS "Count"FRA PetsGROUP BY PetId, PetName, PetTypeORDER BY Count(*) DESC;
Resultat:
PetId PetName PetType Count----- ------- ------- -----4 Bark Dog 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1
Valgmulighed 2
Hvis vi kun vil have de duplikerede rækker på listen, kan vi bruge koden HAVING
klausul for kun at returnere rækker med et antal større end 1:
VÆLG PetId, PetName, PetType, COUNT(*) AS "Count"FRA PetsGROUP BY PetId, PetName, PetTypeHAR COUNT(*)> 1ORDER BY PetId;
Resultat:
PetId PetName PetType Count----- ------- ------- -----1 Wag Dog 2 4 Bark Dog 3
Valgmulighed 3
En anden mulighed er at bruge ROW_NUMBER()
vinduesfunktion:
SELECT *, ROW_NUMBER() OVER ( PARTITION BY PetId, PetName, PetType ORDER BY PetId, PetName, PetType ) AS Row_NumberFROM Pets;
Resultat:
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
PARTITION BY
klausul deler resultatsættet produceret af FROM
klausul i partitioner, som funktionen anvendes på. Når vi angiver partitioner for resultatsættet, får hver partition nummereringen til at starte forfra (dvs. nummereringen starter ved 1 for den første række i hver partition).
Valgmulighed 4
Vi kan bruge ovenstående forespørgsel som et almindeligt tabeludtryk:
MED 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;
Resultat:
PetId PetName PetType Row_Number----- ------- ------- ----------1 Wag Dog 2 4 Bark Dog 2 4 Bark Dog 3Dette returnerer kun de overskydende rækker fra de matchende dubletter. Så hvis der er to identiske rækker, returnerer den en af dem. Hvis der er tre ens rækker, returnerer det to, og så videre.
Denne forespørgsel kan være nyttig til at vise, hvor mange rækker der vil blive fjernet fra tabellen i en de-duping-operation. I nogle andre DBMS'er (i hvert fald i SQL Server) kan vi erstatte den sidste
SELECT *
medDELETE
for at slette de duplikerede rækker fra tabellen. Men SQLite vil ikke lade os opdatere CTE på den måde.Heldigvis kan de næste to muligheder ændres for at udføre en sletning.
Valgmulighed 5
Vi kan drage fordel af SQLites
rovid
:VÆLG * FRA PetsWHERE EXISTS (VÆLG 1 FRA Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType AND Pets.rowid> p2. rowid);
Resultat:
PetId PetName PetType----- ------- -------1 Wag Dog 4 Bark Dog 4 Bark DogHvordan virker det? Som standard har hver række i SQLite en speciel kolonne, normalt kaldet
rowid
, der entydigt identificerer den pågældende række i tabellen. Dette kan fjernes om nødvendigt, men medmindre det udtrykkeligt er blevet fjernet, vil du være i stand til at udnytte det i dine forespørgsler.Valgmulighed 6
Og endelig, her er en anden mulighed, der bruger SQLites
rovid
:SELECT * FROM PetsWHERE rowid> (VÆLG MIN(rowid) FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType);
Resultat:
PetId PetName PetType----- ------- -------1 Wag Dog 4 Bark Dog 4 Bark Dog