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.

  1. INNER JOIN ile LEFT JOIN arasındaki fark nedir?KolayVeritabanı & SQLBackend
  2. Bir tablodaki ikinci en yüksek maaşı bulun.OrtaVeritabanı & SQLBackend
  3. Index nedir? Dezavantajları nelerdir?OrtaVeritabanı & SQLBackend
  4. ACID nedir?OrtaVeritabanı & SQLBackend
  5. Normalizasyon nedir? Ne zaman denormalizasyon yaparsınız?ZorVeritabanı & SQLBackend
  6. N+1 sorgu problemi nedir ve nasıl çözülür?OrtaVeritabanı & SQLBackend

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle