Bir tablodaki tekrar eden (duplicate) kayıtları nasıl bulur ve yalnızca birini bırakarak silersiniz?
Cevap
Önce hangi kolonların "tekrar" tanımını oluşturduğuna karar verilir (ör. email). Sonra GROUP BY ... HAVING COUNT(*) > 1 ile bulunur, window function ile biri hariç silinir.
Tekrarları bulma
SELECT email, COUNT(*) AS adet
FROM users
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY adet DESC;E-postada büyük/küçük harf farkı da tekrar sayılacaksa GROUP BY lower(email) kullanın.
En eski kaydı bırakıp diğerlerini silme
-- PostgreSQL / SQL Server / MySQL 8+
WITH ranked AS (
SELECT id,
ROW_NUMBER() OVER (PARTITION BY email ORDER BY created_at, id) AS rn
FROM users
)
DELETE FROM users
WHERE id IN (SELECT id FROM ranked WHERE rn > 1);SQL Server'da CTE üzerinden doğrudan DELETE FROM ranked WHERE rn > 1 da çalışır. MySQL'de silinen tabloyu alt sorguda kullanma kısıtı varsa self-join kullanılır:
DELETE u1 FROM users u1
JOIN users u2
ON u1.email = u2.email
AND u1.id > u2.id;Tekrarın yeniden oluşmasını önleme
Temizlikten sonra mutlaka kısıt ekleyin:
CREATE UNIQUE INDEX ux_users_email ON users (lower(email));Uygulama tarafında "önce var mı diye kontrol et, sonra ekle" yaklaşımı eşzamanlı isteklerde race condition'a açıktır; doğru çözüm unique constraint + INSERT ... ON CONFLICT DO NOTHING (PostgreSQL) veya INSERT IGNORE / upsert'tir.
Production'da silmeden önce silinecek satırları SELECT ile kontrol edin ve işlemi transaction içinde yapın.
İlgili Veritabanı & SQL soruları
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.