SQL
Поиск и удаление дубликатов
Определение повторяющихся строк по набору полей и безопасное удаление всех копий кроме одной.
Код
-- 1. Найти дубликаты по email
SELECT email, COUNT(*) AS cnt, MIN(id) AS keep_id
FROM users
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY cnt DESC;
-- 2. Посмотреть, что будет удалено (всегда делайте это до DELETE)
WITH ranked AS (
SELECT id, email,
ROW_NUMBER() OVER (PARTITION BY LOWER(email) ORDER BY created_at, id) AS rn
FROM users
)
SELECT * FROM ranked WHERE rn > 1;
-- 3. Удалить, оставив самую раннюю запись
DELETE FROM users
WHERE id IN (
SELECT id FROM (
SELECT id,
ROW_NUMBER() OVER (PARTITION BY LOWER(email) ORDER BY created_at, id) AS rn
FROM users
) t
WHERE t.rn > 1
);
-- 4. Защита на будущее
CREATE UNIQUE INDEX users_email_lower_uniq ON users (LOWER(email));