← Все вопросы

Как удалить дубликаты строк в SQL, оставив по одной?

Задан 19 месяцев назад1к просмотров3 ответа
17

В users есть полные дубли по email (по 2-3 одинаковых записи). Хочу почистить так, чтобы остался ровно один экземпляр каждого. Как удалить лишние, не снеся вообще все повторы?

3 ответа

24
✓ Принятый ответ — помог автору

Идея: оставляем строку с минимальным id в каждой группе, остальные удаляем. На MySQL/PostgreSQL надёжно работает так:

DELETE FROM users
WHERE id NOT IN (
    SELECT min_id FROM (
        SELECT MIN(id) AS min_id
        FROM users
        GROUP BY email
    ) AS keep
);

Внутренний подзапрос возвращает «победителя» каждой группы (самый ранний id), а DELETE сносит всё, чего нет в этом списке. Обёртка через AS keep нужна, потому что MySQL не даёт читать ту же таблицу, которую удаляешь, напрямую.

Обязательно сначала прогони этот SELECT отдельно и проверь, что он возвращает то, что ты ждёшь. И сделай бэкап.

Олег Захаров совет с бэкапом — золотой, DELETE не откатишь без транзакции · 19 месяцев назад
14

В современном PostgreSQL удобнее через оконную функцию:

DELETE FROM users
WHERE id IN (
    SELECT id FROM (
        SELECT id, ROW_NUMBER() OVER (
            PARTITION BY email ORDER BY id
        ) AS rn
        FROM users
    ) t
    WHERE rn > 1
);

ROW_NUMBER нумерует строки внутри каждого email, и мы валим всё, где номер больше 1.

-5

Просто DISTINCT поставь и всё.

Арина Борисова DISTINCT в SELECT ничего не удаляет из таблицы, он только в выборке убирает повторы. вопрос про DELETE · 19 месяцев назад

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект