Následující dotazy lze použít k vrácení duplicitních řádků v SQLite.
Zde duplicitní řádky obsahují duplicitní hodnoty ve všech sloupcích, včetně sloupce ID.
Ukázková data
Předpokládejme, že máme tabulku s následujícími údaji:
SELECT * FROM Pets;
Výsledek:
PetId PetName PetType----- ------- -------1 Wag Dog 1 Wag Dog 2 Scratch Cat 3 Tweet Pták 4 Štěkot psa 4 Štěkot psa 4 Štěkot psa
První dva řádky jsou duplikáty, stejně jako poslední tři řádky. Je to proto, že všechny tři sloupce obsahují stejné hodnoty v každém duplicitním řádku.
Možnost 1
Můžeme použít následující dotaz, abychom viděli, kolik řádků je duplicitních:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY PetId;
Výsledek:
PetId PetName PetType Count----- ------- ------- -----1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bark Dog 3
Zde jsme seskupili řádky podle všech sloupců a vrátili jsme počet řádků každé skupiny. To nám říká, zda je řádek jedinečný (s počtem 1) nebo duplicitní (s počtem větším než 1).
Můžeme to seřadit podle počtu v sestupném pořadí, takže řádky s největším počtem duplikátů se zobrazí jako první:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY Count(*) DESC;
Výsledek:
PetId PetName PetType Count----- ------- ------- -----4 Štěkot psa 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1
Možnost 2
Pokud chceme, aby byly uvedeny pouze duplicitní řádky, můžeme použít HAVING
klauzule pro vrácení pouze řádků s počtem větším než 1:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeHAVING COUNT(*)> 1ORDER BY PetId;
Výsledek:
PetId PetName PetName PetType Count----- ------- ------- -----1 Wag Dog 2 4 Bark Dog 3
Možnost 3
Další možností je použít ROW_NUMBER()
funkce okna:
SELECT *, ROW_NUMBER() OVER ( PARTICE BY PetId, PetName, PetType ORDER BY PetId, PetName, PetType ) AS Row_NumberFROM Pets;
Výsledek:
PetId PetName PetType Row_Number----- ------- ------- ---------- 1 Wag Dog 1 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Pták 1 4 Štěkot psa 1 4 Štěkot psa 2 4 Štěkot psa 3
PARTITION BY
klauzule rozděluje sadu výsledků vytvořenou FROM
klauzule do oddílů, na které je funkce aplikována. Když určíme oddíly pro sadu výsledků, každý oddíl způsobí, že číslování začne znovu (tj. číslování začne na 1 pro první řádek v každém oddílu).
Možnost 4
Výše uvedený dotaz můžeme použít jako společný tabulkový výraz:
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;
Výsledek:
PetId PetName PetType PetType Row_Number----- ------- ------- ----------1 Wag Dog 2 4 Bark Dog 2 4 Bark Dog 3Tím se vrátí pouze přebytečné řádky z odpovídajících duplikátů. Pokud tedy existují dva stejné řádky, vrátí jeden z nich. Pokud existují tři stejné řádky, vrátí dva atd.
Tento dotaz může být užitečný pro zobrazení toho, kolik řádků bude z tabulky odstraněno při operaci odstranění duplikací. V některých jiných DBMS (alespoň v SQL Serveru) můžeme nahradit poslední
SELECT *
pomocíDELETE
k odstranění duplicitních řádků z tabulky. Ale SQLite nám nedovolí takto aktualizovat CTE.Naštěstí lze následující dvě možnosti upravit a provést odstranění.
Možnost 5
Můžeme využít
rowid
SQLite :SELECT * FROM PetsWHERE EXISTS ( SELECT 1 FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType AND Pets.rowid> p2. rowid);
Výsledek:
PetId PetName PetName PetType----- ------- -------1 Wag Dog 4 Bark Dog 4 Bark DogJak to funguje? Ve výchozím nastavení má každý řádek v SQLite speciální sloupec, obvykle nazývaný
rowid
, který jednoznačně identifikuje daný řádek v tabulce. To lze v případě potřeby odstranit, ale pokud nebylo výslovně odstraněno, budete jej moci využít ve svých dotazech.Možnost 6
A nakonec je zde další možnost, která využívá
rowid
SQLite :SELECT * FROM PetsWHERE rowid> ( SELECT MIN(rowid) FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType);
Výsledek:
PetId PetName PetName PetType----- ------- -------1 Wag Dog 4 Bark Dog 4 Bark Dog