CodeRang
Типовые задачи

Дубликаты SQL: как найти и удалить дубли

Дубликаты SQL сначала нужно определить по конкретному набору полей, а затем найти повторяющиеся группы. Разберём, как найти дубликаты SQL через GROUP BY и HAVING и как удалить дубликаты, сохранив нужную строку.

Обновлено · Команда SQL Arena

Что потренируете

  • GROUP BY и HAVING COUNT(*) > 1
  • Нормализация перед сравнением
  • ROW_NUMBER для выбора записи
  • Поиск повторяющихся комбинаций полей
  • Проверка качества данных через SQL

Пример задачи в тренажёре

Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.

Пред.След.Случайная
ЗаданиеОтправкиAI Mentor
Найдите повторяющиеся email после нормализации

В customer_contacts один и тот же email мог быть сохранён несколько раз с разным регистром букв или пробелами по краям. Найдите адреса, которые после нормализации повторяются. Выведите нормализованный адрес в normalized_email и число записей в duplicate_count. Оставьте только значения, встречающиеся больше одного раза.

Запрос 1PostgreSQLv16
SELECT LOWER(TRIM(email)) AS normalized_email,
       COUNT(*) AS duplicate_count
FROM customer_contacts
GROUP BY LOWER(TRIM(email))
HAVING COUNT(*) > 1
ORDER BY normalized_email;
Отправить
Результатcustomerscustomer_contacts
Ответ принят

Как найти дубликаты SQL через GROUP BY и HAVING

В исходных данных Alice@example.com и строка с пробелами вокруг alice@example.com выглядят для человека как один адрес, но текстовые значения различаются. То же происходит с clara@example.com и CLARA@example.com. Поэтому группировка по исходному email пропустила бы часть логических дублей.

LOWER(TRIM(email)) сначала приводит адреса к одной форме: TRIM убирает пробелы по краям, а LOWER переводит буквы в нижний регистр. Уже нормализованное выражение используется и в SELECT, и в GROUP BY. Так критерий отображения совпадает с критерием сравнения.

HAVING COUNT(*) > 1 выполняется после группировки и оставляет только группы, где найдено минимум две строки. В результате появляются три повторяющихся адреса. Этот запрос именно обнаруживает проблему. Если задача состоит в том, чтобы удалить дубли SQL, сначала нужно отдельно определить, какую запись сохранять: самую раннюю, самую новую или выбранную по другому бизнес-правилу.

Найти дубликаты SQL можно только после определения критерия равенства. Иногда достаточно одного поля, а иногда запись считается повторной только по комбинации нескольких колонок. GROUP BY группирует строки по этому критерию, а HAVING COUNT(*) > 1 оставляет только повторяющиеся группы. Если нужно удалить дубликаты SQL, сначала стоит определить, какую строку сохранять. Один из распространённых подходов — присвоить строкам ROW_NUMBER() внутри каждой группы дублей, задать порядок выбора через ORDER BY и удалить записи с номером больше 1.

SQLPostgreSQL v16
SELECT LOWER(TRIM(email)) AS normalized_email,
       COUNT(*) AS duplicate_count
FROM customer_contacts
GROUP BY LOWER(TRIM(email))
HAVING COUNT(*) > 1
ORDER BY normalized_email;
Результат запроса
normalized_emailduplicate_count
alice@example.com2
clara@example.com2
elena@example.com2

Ошибки при поиске и удалении дубликатов SQL

01

Сравнивать только исходное значение

GROUP BY email найдёт только полностью одинаковые строки. Пробелы, регистр и другие варианты записи разделят логически одинаковые значения на разные группы. Нормализацию нужно выбирать под конкретное поле: для email может подойти одна стратегия, для номера телефона или названия компании — другая.

02

Использовать DISTINCT и считать, что проблема решена

DISTINCT скрывает повторения в результате SELECT, но не показывает, какие строки продублированы и сколько их. Исходные записи остаются в таблице. Для диагностики качества данных обычно нужен GROUP BY с COUNT, а для выбора одной строки из группы — оконная нумерация.

03

Удалять все строки из найденной группы

Условие вида «значение встречается больше одного раза» определяет группу дублей, но не говорит, какую запись сохранить. Для безопасного удаления часто сначала считают ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...), оставляют rn = 1 и рассматривают rn > 1 как кандидатов на удаление.

Задачи по теме в тренажёре

Трек «SQL для тестировщика»

Дубликаты бывают не только одинаковыми email. Они появляются после повторной отправки запросов, ошибочного JOIN, повторных платежей, импорта одних и тех же сущностей и неаккуратной обработки текста. В SQL Arena можно начать с бесплатных Easy-задач на повторяющиеся email и размножение строк после JOIN, а затем перейти к поиску повторных событий во временном окне и выбору одной канонической записи. Для практики именно с проверками данных подходит трек «SQL для тестировщика».

Частые вопросы

Как найти дубликаты SQL?

Сгруппируйте строки по полям, которые определяют дубликат, и добавьте HAVING COUNT(*) > 1. Результат покажет значения или комбинации значений, встречающиеся более одного раза.

Как найти дубликаты в SQL через GROUP BY?

Укажите нужные колонки в GROUP BY и посчитайте строки через COUNT(*). Условие HAVING COUNT(*) > 1 оставит только группы с повторами.

Как удалить дубликаты SQL?

Сначала определите правило, по которому одна строка должна остаться. Затем можно пронумеровать строки через ROW_NUMBER() внутри каждой группы дублей и удалить записи, чей номер больше 1.

Как найти дубликаты без учёта регистра и пробелов?

Сравнивайте нормализованное выражение, например LOWER(TRIM(column)), если такая нормализация соответствует смыслу данных. То же выражение нужно использовать как критерий группировки.

Чем DISTINCT отличается от поиска дубликатов?

DISTINCT удаляет повторяющиеся строки из результата SELECT, но не показывает, сколько раз они встречались в исходных данных. Для поиска повторов обычно используют GROUP BY вместе с HAVING COUNT(*) > 1.

Практика поиска дубликатов в SQL

В SQL Arena есть задачи на повторяющиеся значения, дубли после JOIN, идемпотентность, повторные события и выбор единственной записи из группы. Решения проверяются на скрытых данных, поэтому запрос должен работать не только на видимом примере. Всего доступно 1 192 задачи, а 292 бесплатные задачи можно решать бесплатно на PostgreSQL, MySQL, ClickHouse и BigQuery. Для QA-сценариев можно продолжить в треке «SQL для тестировщика».

Решать задачи на дубликаты