sql >> Databáze >  >> RDS >> SQLite

11 způsobů, jak najít duplicitní řádky při ignorování primárního klíče v SQLite

Zde je jedenáct možností pro vrácení duplicitních řádků v SQLite, když tyto řádky mají primární klíč nebo jiný sloupec jedinečného identifikátoru (ale chcete ignorovat primární klíč).

To znamená, že duplicitní řádky sdílejí přesně stejné hodnoty ve všech sloupcích s výjimkou jejich primárního klíče/sloupce jedinečného ID.

Ukázková data

Pro naše příklady použijeme následující data:

SELECT * FROM Dogs; 

Výsledek:

DogId Jméno Příjmení----- --------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag Johnson  

První dva řádky jsou duplikáty (kromě DogId sloupec, který je primárním klíčem tabulky a obsahuje jedinečnou hodnotu ve všech řádcích). Poslední tři řádky jsou také duplikáty (kromě DogId sloupec).

Sloupec primárního klíče zajišťuje, že neexistují žádné duplicitní řádky, což je dobrá praxe v RDBMS, protože primární klíče pomáhají zajistit integritu dat. Ale protože primární klíče zabraňují duplicitním řádkům, mohou narušit naši schopnost najít duplikáty.

V naší tabulce výše je sloupec primárního klíče rostoucí číslo a jeho hodnota nemá žádný význam a není významná. Pokud tedy chceme najít duplikáty v ostatních sloupcích, musíme tento řádek ignorovat.

Možnost 1

Můžeme spustit dotaz pomocí GROUP BY klauzule k seskupení sloupců podle jejich významných sloupců, pak použijte COUNT() funkce, která vrátí počet identických řádků:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
ORDER BY Count DESC; 

Výsledek:

Jméno Příjmení Počet--------- -------- -----Wag Johnson 3 Bark Smith 2 Ruff Robinson 1 Woof Jones 1 

Zde jsme vyloučili sloupec primárního klíče jeho vynecháním z našeho dotazu. Také jsme to seřadili podle počtu v sestupném pořadí, aby se jako první objevily duplikáty.

Výsledek nám říká, že existují tři řádky obsahující Wag Johnson a dva řádky obsahující Bark Smith. Jedná se o duplikáty (nebo triplikáty v případě Waga Johnsona). Další dva řádky nemají žádné duplikáty.

Možnost 2

Můžeme použít HAVING klauzule k vyloučení neduplikátů z výstupu:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1
ORDER BY Count DESC; 

Výsledek:

Jméno Příjmení Počet--------- -------- -----Wag Johnson 3 Bark Smith 2 

Možnost 3

Zde je příklad kontroly duplikátů ve zřetězených sloupcích. V tomto případě použijeme DISTINCT klíčové slovo, abyste získali odlišné hodnoty, pak použijte COUNT() funkce, která vrátí počet:

SELECT
    DISTINCT FirstName || ' ' || LastName AS DogName,
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName || ' ' || LastName
ORDER BY Count DESC; 

Výsledek:

Počet jmen psů------------- -----Wag Johnson 3 Bark Smith 2 Woof Jones 1 Ruff Robinson 1 

Možnost 4

Ve výchozím nastavení má každý řádek v SQLite speciální sloupec, který se obvykle nazývá rowid , který jednoznačně identifikuje daný řádek v tabulce. Pokud nebyl explicitně odstraněn z tabulky, můžete jej použít jako jedinečný identifikátor pro každý řádek.

Můžeme tedy použít rowid v našem dotazu:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
); 

Výsledek:

DogId FirstName Příjmení----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Mohli bychom nahradit SELECT * pomocí DELETE k provedení operace odstranění duplikace na stole.

Všimněte si, že jsme mohli použít DogId (náš primární klíč) namísto rowid kdybychom chtěli. To znamená, že rowid může být užitečné, pokud z nějakého důvodu nemůžete použít sloupec primárního klíče nebo pokud tabulka primární klíč nemá.

Možnost 5

Zde je další dotaz, který používá rowid :

SELECT * FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
); 

Výsledek:

DogId FirstName Příjmení----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Stejně jako v předchozím příkladu bychom mohli nahradit SELECT * pomocí DELETE k odstranění duplicitních řádků.

Možnost 6

Dva rowid výše uvedené možnosti jsou skvělé, pokud musíte primární klíč v dotazu zcela ignorovat (nebo pokud sloupec primárního klíče vůbec nemáte). Jak však bylo zmíněno, stále existuje možnost nahradit rowid se sloupcem primárního klíče – v našem případě DogId sloupec:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
); 

Výsledek:

DogId FirstName Příjmení----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Možnost 7

A zde je další dotaz s rowid nahrazeno DogId sloupec:

SELECT * FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
); 

Výsledek:

DogId FirstName Příjmení----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Možnost 8

Dalším způsobem, jak to udělat, je použít ROW_NUMBER() funkce okna:

SELECT 
    *,
    ROW_NUMBER() OVER ( 
        PARTITION BY FirstName, LastName 
        ORDER BY FirstName, LastName
        ) AS Row_Number
FROM Dogs; 

Výsledek:

DogId Jméno Příjmení Row_Number----- --------- -------- ----------1 Bark Smith 1 2 Bark Smith 2 4 Ruff Robinson 1 5 Wag Johnson 1 6 Wag Johnson 2 7 Wag Johnson 3 3 Woof Jones 1 

Pomocí PARTITION klauzule má za následek přidání nového sloupce s číslem řádku, které se zvýší pokaždé, když existuje duplikát, ale znovu se resetuje, když existuje jedinečný řádek.

V tomto případě výsledky neseskupujeme, což znamená, že můžeme vidět každý duplicitní řádek, včetně sloupce s jedinečným identifikátorem.

Možnost 9

Předchozí příklad můžeme také použít jako běžný tabulkový výraz ve větším dotazu:

WITH cte AS 
    (
        SELECT 
            *,
            ROW_NUMBER() OVER ( 
                PARTITION BY FirstName, LastName 
                ORDER BY FirstName, LastName
                ) AS Row_Number
        FROM Dogs
    )
SELECT * FROM cte WHERE Row_Number <> 1; 

Výsledek:

DogId Jméno Příjmení Row_Number----- --------- -------- ----------2 Bark Smith 2 6 Wag Johnson 2 7 Wag Johnson 3 

To vylučuje neduplikáty z výstupu a vylučuje jeden řádek každého duplikátu z výstupu.

Možnost 10

Zde je další způsob, jak získat stejný výstup jako v předchozím příkladu:

SELECT * FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    ); 

Výsledek:

DogId FirstName Příjmení----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Možnost 11

Zde je další možnost výběru duplikátů z naší tabulky:

SELECT * 
FROM Dogs d1, Dogs d2 
WHERE d1.FirstName = d2.FirstName 
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId 
AND d1.DogId = (
    SELECT MAX(DogId) 
    FROM Dogs d3 
    WHERE d3.FirstName = d1.FirstName 
    AND d3.LastName = d1.LastName
); 

Výsledek:

DogId Jméno Příjmení DogId Jméno Příjmení----- --------- -------- ----- --------- ----- ---2 Bark Smith 1 Bark Smith 7 Wag Johnson 5 Wag Johnson 7 Wag Johnson 6 Wag Johnson 

  1. Tipy k tabulce Microsoft Access – triky a pokyny, část 5

  2. Jak kombinovat datum z jednoho pole s časem z jiného pole - MS SQL Server

  3. Jak nasadit klastr MariaDB pro vysokou dostupnost

  4. Co je jako logický operátor v SQL Server - SQL Server / TSQL výukový program, část 123