Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як знайти дублікати в таблиці й залишити по одному запису?

Знайти дублікати - групування за колонками, що мали б бути унікальними:

SELECT email, COUNT(*) AS copies, MIN(id) AS keep_id
FROM users
GROUP BY email
HAVING COUNT(*) > 1;

Побачити всі рядки-дублікати з порядковим номером - віконна функція:

SELECT *
FROM (
    SELECT u.*,
           ROW_NUMBER() OVER (PARTITION BY email ORDER BY created_at, id) AS rn
    FROM users u
) t
WHERE rn > 1;    -- усе, крім першого запису кожного email

ORDER BY визначає, який запис залишити: найстаріший, найновіший, найповніший.

Видалити дублікати:

DELETE u
FROM users u
JOIN (
    SELECT id
    FROM (
        SELECT id, ROW_NUMBER() OVER (PARTITION BY email ORDER BY created_at, id) AS rn
        FROM users
    ) ranked
    WHERE rn > 1
) dup ON dup.id = u.id;

Подвійне вкладення обходить обмеження MySQL на читання з тієї ж таблиці, з якої видаляють.

Перш ніж видаляти:

  • Злити пов'язані дані: замовлення, коментарі, підписки дублікатів перепризначити на запис, що залишається. Інакше вони або зникнуть каскадом, або залишаться «сиротами».
  • Нормалізувати значення: Olia@Example.com і olia@example.com - теж дублікати, якщо порівнювати з урахуванням регістру й пробілів.
  • Зробити бекап або перенести дублікати в окрему таблицю, а не видаляти одразу.

Головне - не допустити повторення: додати унікальний індекс після очищення (ALTER TABLE users ADD UNIQUE (email)). Без нього дублікати з'являться знову - через гонку двох одночасних реєстрацій чи імпорт.

Докладніше в документації: Використання віконних функцій

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання