SQLite
 sql >> Baza danych >  >> RDS >> SQLite

11 sposobów na znalezienie zduplikowanych wierszy, ignorując klucz podstawowy w SQLite

Oto jedenaście opcji zwracania zduplikowanych wierszy w SQLite, gdy te wiersze mają klucz podstawowy lub inną kolumnę unikatowego identyfikatora (ale chcesz zignorować klucz podstawowy).

Oznacza to, że zduplikowane wiersze mają dokładnie te same wartości we wszystkich kolumnach z wyjątkiem kolumny klucza podstawowego/unikalnego identyfikatora.

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 jest dobrą praktyką w systemach RDBMS, ponieważ klucze podstawowe pomagają wymusić integralność danych. Ale ponieważ klucze podstawowe zapobiegają duplikowaniu wierszy, mogą one potencjalnie zakłócać naszą zdolność do znajdowania duplikatów.

W naszej tabeli powyżej 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 innych kolumnach.

Opcja 1

Możemy uruchomić zapytanie za pomocą 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
ORDER BY Count DESC;

Wynik:

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

Tutaj wykluczyliśmy kolumnę klucza podstawowego, pomijając ją w naszym zapytaniu. Uporządkowaliśmy je również według liczby w porządku malejącym, tak aby duplikaty pojawiały się jako pierwsze.

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

Opcja 2

Możemy użyć HAVING klauzula wykluczająca nieduplikaty z danych wyjściowych:

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

Wynik:

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

Opcja 3

Oto przykład sprawdzania duplikatów w połączonych kolumnach. W tym przypadku używamy DISTINCT słowa kluczowego, aby uzyskać różne wartości, a następnie użyj COUNT() funkcja zwracająca liczbę:

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

Wynik:

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

Opcja 4

Domyślnie każdy wiersz w SQLite ma specjalną kolumnę, zwykle nazywaną rowid , który jednoznacznie identyfikuje ten wiersz w tabeli. O ile nie został wyraźnie usunięty z tabeli, możesz użyć go jako unikalnego identyfikatora dla każdego wiersza.

Możemy zatem użyć rowid w naszym zapytaniu:

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

Wynik:

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

Moglibyśmy zastąpić SELECT * z DELETE aby wykonać operację usuwania duplikatów na stole.

Zauważ, że mogliśmy użyć DogId kolumna (nasz klucz podstawowy) zamiast rowid gdybyśmy chcieli. To powiedziawszy, rowid może być przydatne, jeśli z jakiegoś powodu nie możesz użyć kolumny klucza podstawowego lub jeśli tabela nie ma klucza podstawowego.

Opcja 5

Oto kolejne zapytanie, które używa rowid :

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

Wynik:

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

Podobnie jak w poprzednim przykładzie, możemy zastąpić SELECT * z DELETE aby usunąć zduplikowane wiersze.

Opcja 6

Dwa rowid powyższe opcje są świetne, jeśli musisz całkowicie zignorować klucz podstawowy w zapytaniu (lub jeśli w ogóle nie masz kolumny klucza podstawowego). Jednak jak wspomniano, nadal istnieje możliwość zastąpienia rowid z kolumną klucza podstawowego – w naszym przypadku DogId kolumna:

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

Wynik:

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

Opcja 7

A oto inne zapytanie z rowid zastąpione przez DogId kolumna:

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

Wynik:

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

Opcja 8

Innym sposobem na to jest użycie ROW_NUMBER() funkcja okna:

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         
5      Wag        Johnson   1         
6      Wag        Johnson   2         
7      Wag        Johnson   3         
3      Woof       Jones     1         

Korzystanie z PARTITION klauzula powoduje dodanie nowej kolumny z numerem wiersza, który zwiększa się za każdym razem, gdy pojawia się duplikat, ale resetuje się ponownie, gdy istnieje 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 9

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         
6      Wag        Johnson   2         
7      Wag        Johnson   3         

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

Opcja 10

Oto inny 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 

Opcja 11

Oto kolejna opcja wyboru duplikatów z naszej tabeli:

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. Sprawdź, czy ciąg kolumn w bazie danych jest podciągiem zapytania w sqlite

  2. SQLite JSON_EXTRACT()

  3. Dostrajanie wydajności SQLite

  4. Jak wstawić dużą ilość danych do bazy danych sqlite w systemie Android

  5. Jak uzyskać dostęp i zaktualizować plik db Sqlite przechowywany lokalnie [folder zasobów] w pliku projektu za pomocą cordova?