Способы удаления дубликатов в SQL Server
При проектировании объектов, в частности таблиц в БД SQL Server, необходимо придерживаться определенных правил. Однако, даже если следовать данным правилам существует вероятность появления дубликатов в строках таблиц. Данная статья посвящена различным способам очистки данных от дубликатов.
При проектировании объектов, в частности таблиц в БД SQL Server необходимо придерживаться определенных правил: рекомендуется использовать правила нормализации БД; таблица должна иметь первичные ключи, кластерные и некластерные индексы; ограничения для обеспечения целостности данных и производительности. Но даже если следовать этим правилам, мы можем столкнуться с проблемой появления дубликатов в строках таблицы. Кроме этого, возможна ситуация получения дубликатов при импорте данных, когда мы загружаем данные as is в промежуточные таблицы, и далее требуется удалить дублирующие записи перед загрузкой в промышленные таблицы.
Рассмотрим различные способы для очистки данных от дублей. Создадим простую таблицу сотрудников и наполним её несколькими записями.
Как мы видим, в таблице присутствуют дублирующие строки, которые необходимо удалить.
- Удаление дубликатов с использованием агрегатных функций
C помощью условия GROUP BY мы группируем данные по определенным столбцам и используем функцию COUNT для подсчета вхождений строк в таблицу.
Например, с помощью следующего запроса, определим записи, которые присутствуют в таблице более 1 раза.
Т.е. сотрудники Алексеев А.А. и Иванов И.И. присутствуют в таблице 3 и 2 раза соответственно.
Удалим дублирующие записи, оставив только строки с MIN id сотрудника.
Выведем оставшиеся записи таблицы, и убедимся, что дубликаты отсутствуют.
Отметим, что данный способ удаления дубликатов возможен в случае таблиц, для которых определен первичный ключ.
- Удаление дубликатов используя обобщенные табличные выражения (CTE)
Мы можем использовать связку обобщенных табличных выражений и функции ROW_number() для удаления дубликатов, например следующим образом:
В данном запросе мы используем функцию ROW_number() с конструкцией partition BY в предложении OVER для нумерации записей, и удаляем записи с пронумерованными значениями > 1, соответствующие дубликатам.
- Удаление дубликатов с использованием инструментария SSIS пакетов.
Создадим в SQL Server Data Tools новый пакет integration Services.
Добавим в пакет элемент «OLE DB Source», откроем редактор OLE DB Source, в графе Connection Manager укажем реквизиты экземпляра СУБД и БД, и наименование исходной таблицы с данными, содержащей дубликаты.
С помощью кнопки Preview убедимся, что в исходной таблице присутствуют дубликаты.
Добавим оператор «Sort», и выделим поля, в которых присутствуют дублирующие данные.
Установим галку «Remove rows with duplicate sort values» для удаления дубликатов.
Добавим элемент «OLE DB Destination», в котором укажем целевую таблицу для записей результата очистки данных.
Запустив на исполнение реализованный SSIS пакет, мы видим, что в целевой источник загрузилось 3 строки, проверим, что отсутствуют дубликаты.
Необходимо отметить, что при использовании данного способа потребуется дополнительное место для хранения новой целевой таблицы, однако данный вариант позволяет избежать ошибок и вернуться к исходному варианту, в случае если результат в целевой таблице не будет являться удовлетворительным.
В данной статье мы рассмотрели различные способы удаления дубликатов записей в таблицах БД SQL Server, которые могут быть использованы в работе в зависимости от задачи и объема данных.
При больших объемах дубликатов в данных целесообразно рассмотреть возможность сохранения уникальных значений в промежуточную таблицу, очистку рабочей таблицы, и возврат оставленных уникальных записей.
Find duplicate records in MySQL
I want to pull out duplicate records in a MySQL Database. This can be done with:
Which results in:
I would like to pull it so that it shows each row that is a duplicate. Something like:
Any thoughts on how this can be done? I’m trying to avoid doing the first one then looking up the duplicates with a second query in the code.
28 Answers 28
The key is to rewrite this query so that it can be used as a subquery.
Why not just INNER JOIN the table with itself?
A DISTINCT is needed if the address could exist more than two times.
I tried the best answer chosen for this question, but it confused me somewhat. I actually needed that just on a single field from my table. The following example from this link worked out very well for me:
Isn’t this easier :
10 000 duplicate rows in order to make them unique, much faster than load all 600 000 rows.
This is the similar query you have asked for and its 200% working and easy too. Enjoy.
Find duplicate users by email address with this query.
![]()
we can found the duplicates depends on more then one fields also.For those cases you can use below format.
![]()
Finding duplicate addresses is much more complex than it seems, especially if you require accuracy. A MySQL query is not enough in this case.
I work at SmartyStreets, where we do address validation and de-duplication and other stuff, and I’ve seen a lot of diverse challenges with similar problems.
There are several third-party services which will flag duplicates in a list for you. Doing this solely with a MySQL subquery will not account for differences in address formats and standards. The USPS (for US address) has certain guidelines to make these standard, but only a handful of vendors are certified to perform such operations.
So, I would recommend the best answer for you is to export the table into a CSV file, for instance, and submit it to a capable list processor. One such is LiveAddress which will have it done for you in a few seconds to a few minutes automatically. It will flag duplicate rows with a new field called "Duplicate" and a value of Y in it.
Как вывести дубликаты в sql

Создание игр на Unreal Engine 5
Данный курс научит Вас созданию игр на Unreal Engine 5. Курс состоит из 12 модулей, в которых Вы с нуля освоите этот движок и сможете создавать самые разные игры.
В курсе Вы получите всю необходимую теоретическую часть, а также увидите массу практических примеров. Дополнительно, почти к каждому уроку идут упражнения для закрепления материала.
Помимо самого курса Вас ждёт ещё 8 бесплатных ценных Бонусов: «Chaos Destruction», «Разработка 2D-игры», «Динамическая смена дня и ночи», «Создание динамической погоды», «Создание искусственного интеллекта для NPC», «Создание игры под мобильные устройства», «Создание прототипа RPG с открытым миром» и и весь курс «Создание игр на Unreal Engine 4» (актуальный и в 5-й версии), включающий в себя ещё десятки часов видеоуроков.
Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.
Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.
Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.
Мой аккаунт Моя группа
Зачем Вы изучаете программирование/создание сайтов?
Основы Unreal Engine 5
Пройдя курс:
— Вы получите необходимую базу по Unreal Engine 5
— Вы познакомитесь с множеством инструментов в движке
— Вы научитесь создавать несложные игры
Общая продолжительность курса 4 часа, плюс множество упражнений и поддержка!
Ищем дубликаты записей в базе данных
Недавно мне понадобилось сделать на одном сайте такую систему страниц, чтобы к любой сущности (пост в блоге, страничка автора поста, просто статическая страница) можно было обратиться по её коду, а не по ID. Причём этот код должен идти сразу за адресом самого сайта — без каких бы то ни было папок, подпапок и прочих слэшей в пути. Примерно вот так:
- http://sitename.org/cool_post
- http://sitename.org/even_cooler_post_author
- http://sitename.org/just_a_static_page
Разумеется, чтобы это реализовать, надо убедиться, что коды сущностей уникальны. Я не буду рассказывать, как я добавлял единички к кодам, когда они совпадали, я расскажу о том, как я искал одинаковые коды.
Одна таблица
Начнём с простого — с одной единственной таблицы такого вида:
| id | code | title | text |
|---|---|---|---|
| 1 | code1 | name1 | text1 |
| 2 | code2 | name2 | text2 |
| 3 | code3 | name3 | text3 |
Здесь у нас id — это первичный ключ, он уникален. А поле code — просто некий код, который может повторяться для разных записей. Если быть совсем точным, то я сгенерировал коды просто транслитерировав названия.
Теперь мы хотим найти все повторы. Будем выводить сам повторяющийся код, список Idшек и количество повторов.
MySQL
Для нашего примера получим такой вывод:
| code | ids | cnt |
|---|---|---|
| code2 | 2, 3 | 2 |
PostgreSQL
Особенность PostgreSQL’я в том, что функция конкатенации строк работает только с текстом, поэтому числовые Idшники нужно сначала привести к типу text.
MSSQL
В MSSQL нет агрегирующей функции для конкатенации, поэтому придётся использовать хитрый подзапрос.
Много таблиц
Теперь вернёмся к исходной задаче: нам нужны уникальные коды не в одной таблице, а сразу в нескольких. Возьмём для примера такие:
| id | code | title | text |
|---|---|---|---|
| 1 | code1 | name1 | text1 |
| 2 | code2 | name2 | text2 |
| 3 | code3 | name3 | text3 |
Таблица Article
| id | code | title | text |
|---|---|---|---|
| 1 | code2 | name2 | text2 |
| 2 | code3 | name3 | text3 |
| 3 | code4 | name4 | text4 |
Таблица Author
| id | code | title | text |
|---|---|---|---|
| 1 | code3 | name3 | text3 |
| 2 | code4 | name4 | text4 |
| 3 | code5 | name5 | text5 |
Теперь вместо IDшников я буду выводить названия таблиц, где встречаются одинаковые записи.
В сущности, запрос останется прежним, только теперь выборку будем делать из временной таблицы, в которой объединим все остальные.
MySQL
MSSQL
В MSSQL исходная таблица нам нужна в двух местах — в выборке и в грязном хаке, заменяющем конкатенацию, поэтому будет проще, если мы сделаем для неё синоним.
Заключение
А в конце хочется сказать, что вся эта статья была затеяна только ради конкатенации в MSSQL:)