MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

7 sposobów na zwrócenie zduplikowanych wierszy, które mają klucz podstawowy w MariaDB

Oto siedem sposobów zwracania zduplikowanych wierszy w MariaDB, gdy te wiersze mają klucz podstawowy lub inną kolumnę unikatowego identyfikatora.

Dlatego zduplikowane wiersze mają dokładnie te same wartości we wszystkich kolumnach, z wyjątkiem kolumny z unikalnym identyfikatorem.

Przykładowe dane

W naszych przykładach użyjemy następujących danych:

SELECT * FROM Dogs;

Wynik:

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

Pierwsze dwa wiersze są duplikatami (z wyjątkiem DogId kolumna, która jest kluczem podstawowym tabeli i zawiera unikatową wartość we wszystkich wierszach). Ostatnie trzy wiersze również są duplikatami (z wyjątkiem DogId kolumna).

Kolumna klucza podstawowego zapewnia, że ​​nie ma zduplikowanych wierszy, co zwykle jest dobrą rzeczą w systemach RDBMS. Jednak z definicji oznacza to, że nie ma duplikatów. W naszym przypadku kolumna klucza podstawowego jest liczbą rosnącą, a jej wartość nie ma znaczenia i nie jest istotna. Dlatego musimy zignorować ten wiersz, jeśli chcemy znaleźć duplikaty w kolumnach, które istotne.

Opcja 1

Możemy użyć GROUP BY klauzula, aby pogrupować kolumny według ich znaczących kolumn, a następnie użyj COUNT() funkcja zwracająca liczbę identycznych wierszy:

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

Wynik:

+-----------+----------+-------+
| FirstName | LastName | Count |
+-----------+----------+-------+
| Bark      | Smith    |     2 |
| Ruff      | Robinson |     1 |
| Wag       | Johnson  |     3 |
| Woof      | Jones    |     1 |
+-----------+----------+-------+

Udało nam się wykluczyć kolumnę klucza podstawowego, pomijając ją w naszym zapytaniu.

Wynik mówi nam, że istnieją dwa wiersze zawierające Bark Smith i trzy wiersze zawierające Wag Johnson. Są to duplikaty (lub trzy egzemplarze w przypadku Wag Johnson). Pozostałe dwa wiersze nie mają żadnych duplikatów.

Opcja 2

Możemy wykluczyć nieduplikaty z danych wyjściowych za pomocą HAVING klauzula:

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

Wynik:

+-----------+----------+-------+
| FirstName | LastName | Count |
+-----------+----------+-------+
| Bark      | Smith    |     2 |
| Wag       | Johnson  |     3 |
+-----------+----------+-------+

Opcja 3

Możliwe jest również sprawdzenie duplikatów w połączonych kolumnach. Na przykład możemy użyć CONCAT() do łączenia naszych dwóch kolumn użyj funkcji DISTINCT słowa kluczowego, aby uzyskać różne wartości, a następnie użyj COUNT() funkcja zwracająca liczbę:

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

Wynik:

+---------------+-------+
| DogName       | Count |
+---------------+-------+
| Bark Smith    |     2 |
| Ruff Robinson |     1 |
| Wag Johnson   |     3 |
| Woof Jones    |     1 |
+---------------+-------+

Opcja 4

Możemy użyć ROW_NUMBER() funkcja z PARTITION BY klauzula:

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

Wynik:

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

Spowoduje to utworzenie nowej kolumny z numerem wiersza, który zwiększa się za każdym razem, gdy pojawia się duplikat, ale resetuje się ponownie, gdy pojawia się unikalny wiersz.

W tym przypadku nie grupujemy wyników, co oznacza, że ​​możemy zobaczyć każdy zduplikowany wiersz, w tym jego kolumnę z unikalnym identyfikatorem.

Opcja 5

Możemy również użyć poprzedniego przykładu jako wspólnego wyrażenia tabelowego w większym zapytaniu:

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;

Wynik:

+-------+-----------+----------+------------+
| DogId | FirstName | LastName | Row_Number |
+-------+-----------+----------+------------+
|     2 | Bark      | Smith    |          2 |
|     5 | Wag       | Johnson  |          2 |
|     7 | Wag       | Johnson  |          3 |
+-------+-----------+----------+------------+

Wyklucza to nieduplikaty z danych wyjściowych i wyklucza jeden wiersz każdego duplikatu z danych wyjściowych.

To zapytanie może być używane jako prekursor operacji usuwania duplikatów. Może nam pokazać, co zostanie usunięte, jeśli zdecydujemy się usunąć duplikaty. Aby usunąć duplikat tabeli, wystarczy zastąpić ostatni SELECT * z DELETE .

Opcja 6

Oto bardziej zwięzły sposób na uzyskanie tego samego wyniku, co w poprzednim przykładzie:

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

Wynik:

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

Ten przykład nie wymaga generowania własnego oddzielnego numeru wiersza.

Możemy zastąpić SELECT * z DELETE aby usunąć duplikaty.

Opcja 7

I wreszcie, oto kolejna opcja zwracania duplikatów:

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
);

Wynik:

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

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak skonfigurować replikację asynchroniczną między klastrami MariaDB Galera

  2. Monitorowanie klastra Galera dla MySQL lub MariaDB — zrozumienie metryk (zaktualizowane)

  3. Popraw wydajność klastra Galera dla MySQL lub MariaDB

  4. Jak SUBDATE() działa w MariaDB

  5. Zautomatyzowane testowanie procesu aktualizacji dla MySQL/MariaDB/Percona Server