Как удалить дубликаты строк в SQL, оставив по одной?
В users есть полные дубли по email (по 2-3 одинаковых записи). Хочу почистить так, чтобы остался ровно один экземпляр каждого. Как удалить лишние, не снеся вообще все повторы?
3 ответа
Идея: оставляем строку с минимальным 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 отдельно и проверь, что он возвращает то, что ты ждёшь. И сделай бэкап.
В современном 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.
Просто DISTINCT поставь и всё.