Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

4 начина за проверка за дублиращи се редове в SQL Server

Ето четири метода, които можете да използвате, за да намерите дублиращи се редове в SQL Server.

Под „дублирани редове“ имам предвид два или повече реда, които споделят абсолютно еднакви стойности във всички колони.

Примерни данни

Да предположим, че имаме таблица със следните данни:

SELECT * FROM Pets;

Резултат:

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

Можем да видим, че първите два реда са дублирани, както и последните три реда.

Опция 1

Можем да използваме следната заявка, за да върнем информация за дублиращи се редове:

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

Резултат:

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

Можем да разширим SELECT списък, за да включите още колони, ако е необходимо:

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

Резултат:

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

Ако таблицата има уникален идентификатор, можем просто да премахнем тази колона от заявката. Например, ако приемем, че PetId колоната всъщност е колона с първичен ключ, която съдържа уникален идентификатор, бихме могли да изпълним следната заявка, за да върнем всички редове, които са дублирани, без да броим колоната с първичен ключ:

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

Резултат:

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

Опция 2

Ако искаме да се върнат само действителните дублиращи се редове, можем да добавим HAVING клауза:

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

Резултат:

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

Опция 3

Друг начин да го направите е да използвате ROW_NUMBER() функция с PARTITION BY клауза за номериране на изхода на резултатния набор.

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

Резултат:

+---------+-----------+-----------+--------------+
| 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 клауза разделя резултатния набор, произведен от FROM клауза в дялове, към които се прилага функцията. Когато посочим дялове за резултатния набор, всеки дял кара номерирането да започне отново (т.е. номерирането ще започне от 1 за първия ред във всеки дял).

Опция 4

Ако искаме да се връщат само излишни редове от съвпадащите дубликати, можем да използваме горната заявка като общ табличен израз, както следва:

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;

Резултат:

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

Едно от предимствата на това е, че можем да изтрием дублиращи се редове просто чрез превключване на SELECT * до DELETE (на последния ред).

Следователно можем да използваме горния код, за да видим кои редове ще бъдат изтрити и след това, когато сме доволни, че ще изтрием правилните редове, можем да го превключим на DELETE изявление, за да ги изтриете.

Като това:

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. Как мога да намеря символи Unicode/не-ASCII в поле NTEXT в таблица на SQL Server 2005?

  2. Преобразуване на ‘time’ в ‘datetimeoffset’ в SQL Server (T-SQL примери)

  3. Как да създадете уникално ограничение за множество колони в SQL Server - SQL Server / TSQL урок, част 96

  4. Управлявайте паралелността на транзакциите с помощта на заключвания в SQL Server

  5. Как да генерирате drop Unique Constraint скриптове в база данни на SQL Server - SQL Server / TSQL Урок, част 99