Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

4 sposoby sprawdzania zduplikowanych wierszy w SQL Server

Oto cztery metody, których można użyć do znalezienia zduplikowanych wierszy w programie SQL Server.

Przez „zduplikowane wiersze” rozumiem dwa lub więcej wierszy, które mają dokładnie te same wartości we wszystkich kolumnach.

Przykładowe dane

Załóżmy, że mamy tabelę z następującymi danymi:

SELECT * FROM Pets;

Wynik:

+---------+-----------+-----------+
| PetId   | PetName   | PetType   |
|---------+-----------+-----------|
| 1       | Wag       | Dog       |
| 1       | Wag       | Dog       |
| 2       | Scratch   | Cat       |
| 3       | Tweet     | Bird      |
| 4       | Bark      | Dog       |
| 4       | Bark      | Dog       |
| 4       | Bark      | Dog       |
+---------+-----------+-----------+

Widzimy, że pierwsze dwa wiersze są duplikatami, podobnie jak ostatnie trzy wiersze.

Opcja 1

Możemy użyć następującego zapytania, aby zwrócić informacje o zduplikowanych wierszach:

SELECT 
    DISTINCT PetId, 
    COUNT(*) AS "Count"
FROM Pets
GROUP BY PetId
ORDER BY PetId;

Wynik:

+---------+---------+
| PetId   | Count   |
|---------+---------|
| 1       | 2       |
| 2       | 1       |
| 3       | 1       |
| 4       | 3       |
+---------+---------+

Możemy rozwinąć SELECT lista zawierająca więcej kolumn, jeśli jest to wymagane:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Wynik:

+---------+-----------+-----------+---------+
| PetId   | PetName   | PetType   | Count   |
|---------+-----------+-----------+---------|
| 1       | Wag       | Dog       | 2       |
| 2       | Scratch   | Cat       | 1       |
| 3       | Tweet     | Bird      | 1       |
| 4       | Bark      | Dog       | 3       |
+---------+-----------+-----------+---------+

Jeśli tabela ma unikalny identyfikator, możemy po prostu usunąć tę kolumnę z zapytania. Na przykład, jeśli założymy, że PetId kolumna jest w rzeczywistości kolumną klucza podstawowego zawierającą unikalny identyfikator, moglibyśmy uruchomić następujące zapytanie, aby zwrócić wszystkie wiersze, które są duplikatami, nie licząc kolumny klucza podstawowego:

SELECT 
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetName,
    PetType
ORDER BY PetName;

Wynik:

+-----------+-----------+---------+
| PetName   | PetType   | Count   |
|-----------+-----------+---------|
| Bark      | Dog       | 3       |
| Scratch   | Cat       | 1       |
| Tweet     | Bird      | 1       |
| Wag       | Dog       | 2       |
+-----------+-----------+---------+

Opcja 2

Jeśli chcemy zwrócić tylko rzeczywiste zduplikowane wiersze, możemy dodać HAVING klauzula:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId;

Wynik:

+---------+-----------+-----------+---------+
| PetId   | PetName   | PetType   | Count   |
|---------+-----------+-----------+---------|
| 1       | Wag       | Dog       | 2       |
| 4       | Bark      | Dog       | 3       |
+---------+-----------+-----------+---------+

Opcja 3

Innym sposobem na to jest użycie ROW_NUMBER() funkcja z PARTITION BY klauzula do numerowania danych wyjściowych zestawu wyników.

SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets;

Wynik:

+---------+-----------+-----------+--------------+
| PetId   | PetName   | PetType   | Row_Number   |
|---------+-----------+-----------+--------------|
| 1       | Wag       | Dog       | 1            |
| 1       | Wag       | Dog       | 2            |
| 2       | Scratch   | Cat       | 1            |
| 3       | Tweet     | Bird      | 1            |
| 4       | Bark      | Dog       | 1            |
| 4       | Bark      | Dog       | 2            |
| 4       | Bark      | Dog       | 3            |
+---------+-----------+-----------+--------------+

PARTITION BY klauzula dzieli zbiór wyników utworzony przez FROM klauzuli na przegrody, do których funkcja jest stosowana. Kiedy określamy partycje dla zestawu wyników, każda partycja powoduje, że numeracja zaczyna się od nowa (tj. numeracja rozpocznie się od 1 dla pierwszego wiersza w każdej partycji).

Opcja 4

Jeśli chcemy, aby zwracane były tylko dodatkowe wiersze z pasujących duplikatów, możemy użyć powyższego zapytania jako wspólnego wyrażenia tabelowego, na przykład:

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;

Wynik:

+---------+-----------+-----------+--------------+
| PetId   | PetName   | PetType   | Row_Number   |
|---------+-----------+-----------+--------------|
| 1       | Wag       | Dog       | 2            |
| 4       | Bark      | Dog       | 2            |
| 4       | Bark      | Dog       | 3            |
+---------+-----------+-----------+--------------+

Jedną z korzyści płynących z tego jest to, że możemy usunąć zduplikowane wiersze po prostu przełączając SELECT * do DELETE (w ostatniej linii).

Dlatego możemy użyć powyższego kodu, aby zobaczyć, które wiersze zostaną usunięte, a następnie, gdy jesteśmy przekonani, że zamierzamy usunąć prawidłowe wiersze, możemy przełączyć go na DELETE oświadczenie, aby faktycznie je usunąć.

Tak:

WITH CTE AS 
    (
        SELECT 
            *, 
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
DELETE FROM CTE WHERE Row_Number <> 1;

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server 2016:Widok projektanta

  2. Zrozumienie blokad SQL Server w zapytaniach SELECT

  3. jak uzyskać daty rozpoczęcia i zakończenia wszystkich tygodni między dwiema datami w serwerze SQL?

  4. Podstawy zarządzania plikami danych w SQL Server

  5. Jak zaimportować duży plik MS SQL .sql?