sql >> Databáze >  >> RDS >> MariaDB

2 způsoby, jak odstranit duplicitní řádky v MariaDB (ignoruje primární klíč)

Zde jsou příklady odstranění duplicitních řádků z tabulky v MariaDB, když tyto řádky mají sloupec primárního klíče nebo jedinečného identifikátoru.

Příklady odstraní duplicitní řádky, ale ponechají jeden. Takže v případě dvou stejných řádků jeden z nich smaže a druhý ponechá.

Ukázková data

Naše příklady používají následující data:

SELECT * FROM Dogs;

Výsledek:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     2 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Vidíme, že první dva řádky jsou duplikáty, stejně jako poslední tři řádky.

DogId sloupec obsahuje jedinečné hodnoty (protože je to primární klíč tabulky), a proto, přísně vzato, neexistují žádné duplikáty. Ale v reálných situacích budete často chtít odstranit duplicitní tabulky, které obsahují primární klíče. Proto v tomto článku ignorujeme primární klíč a ve zbývajících sloupcích zjišťujeme duplicitní hodnoty.

Možnost 1

Začněme naši první možnost výběrem všech řádků, které budou smazány:

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

Výsledek:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     2 | Bark      | Smith    |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Chcete-li odstranit tyto duplicitní řádky, můžeme přepnout SELECT * na DELETE :

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

Výsledek:

Query OK, 3 rows affected (0.017 sec)

A pro ověření výsledku můžeme vybrat všechny zbývající řádky v tabulce:

SELECT * FROM Dogs;

Výsledek:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
+-------+-----------+----------+

Alternativně můžeme použít MAX() místo funkce MIN() funkce pro změnu, které řádky se mají odstranit.

Možnost 2

V tomto příkladu budeme předpokládat, že tabulka byla obnovena do původního stavu (s duplikáty).

Ke kontrole duplicitních řádků můžeme použít následující dotaz:

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 | FirstName | LastName | DogId | FirstName | LastName |
+-------+-----------+----------+-------+-----------+----------+
|     2 | Bark      | Smith    |     1 | Bark      | Smith    |
|     7 | Wag       | Johnson  |     5 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |     6 | Wag       | Johnson  |
+-------+-----------+----------+-------+-----------+----------+

A můžeme tento dotaz upravit tak, aby byly duplikáty odstraněny:

DELETE FROM Dogs WHERE DogId IN (
    SELECT d2.DogId 
    FROM Dogs d1, Dogs d2 
    WHERE d1.FirstName = d2.FirstName 
    AND d1.LastName = d2.LastName 
    AND d1.DogId <> d2.DogId 
    AND d1.DogId=( 
        SELECT MIN(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

Výsledek:

Query OK, 3 rows affected (0.075 sec)

Tabulka byla nyní deduplikována.

Můžeme to ověřit tak, že znovu vybereme všechny řádky:

SELECT * FROM Dogs;

Výsledek:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
+-------+-----------+----------+

Můžeme použít MAX() místo MIN() chcete-li odstranit další řádky z duplikátů.


  1. Index pro nalezení prvku v poli JSON

  2. Získejte datum/čas z unixového časového razítka v SQLite

  3. Jak v Redshift/Postgres počítat řádky, které splňují podmínku?

  4. Jak zobrazit hodnoty Null při spouštění dotazů v psql (PostgreSQL)