Дедупликация в SQL: удаление дублей

6 задач Лёгкие, средние, сложные С эталонными решениями Решение в браузере
Дубликаты — больная тема реальных данных: повторная загрузка в ETL, джойн с фан-аутом, отсутствие уникального ключа. На собеседовании аналитика дедупликацию спрашивают почти всегда: «оставь только последнюю запись по каждому юзеру», «убери полные дубли строк», «посчитай уникальных правильно». Главный инструмент — ROW_NUMBER() OVER (PARTITION BY ключ ORDER BY дата DESC) с фильтром rn = 1; для простых случаев хватает DISTINCT или GROUP BY, а в PostgreSQL есть лаконичный DISTINCT ON. Разбираем все подходы и подводные камни — какой способ дедупа выбрать под задачу и почему.
Начать решать задачи →

Все задачи на «Дедупликация» (6)

FAQ: частые вопросы про дедупликация

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

Стандарт — ROW_NUMBER() OVER (PARTITION BY ключ ORDER BY дата DESC) во CTE, затем WHERE rn = 1: останется одна (последняя) запись на ключ. Для полных дублей строк, где совпадают все колонки, достаточно SELECT DISTINCT или GROUP BY по всем полям.

DISTINCT, GROUP BY или ROW_NUMBER — что выбрать?

DISTINCT и GROUP BY убирают полные дубли строк (совпадают все колонки). ROW_NUMBER нужен, когда дубли по ключу, но строки различаются и надо выбрать конкретную — последнюю по дате, с максимальной суммой. ROW_NUMBER самый гибкий.

Как оставить только последнюю запись по каждому ключу?

ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC) AS rn во CTE, затем WHERE rn = 1. Если при равных датах нужны все строки, а не одна — взять RANK вместо ROW_NUMBER.

Что такое DISTINCT ON в PostgreSQL?

DISTINCT ON (user_id) ... ORDER BY user_id, updated_at DESC — короткий способ взять по одной строке на ключ без оконных функций. Работает только в PostgreSQL; в других СУБД эквивалент — ROW_NUMBER.

Связанные темы SQL

Агрегации · JOIN-запросы · Оконные функции · CTE (Common Table Expressions) · Подзапросы · Работа с датами · Строковые функции · Условная логика

Открыть весь SQL-тренажёр (576 задач) →