Hiç sipariş vermemiş müşterileri bulun. NOT IN ile NOT EXISTS arasındaki NULL tuzağı nedir?

Cevap

Tablolar: customers(id, name) ve orders(id, customer_id, ...). Üç yaygın çözüm vardır; en güvenlisi NOT EXISTS veya LEFT JOIN ... IS NULL'dır.

-- 1) NOT EXISTS (önerilen)
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM orders o WHERE o.customer_id = c.id
);

-- 2) LEFT JOIN anti-join
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;

-- 3) NOT IN (tehlikeli)
SELECT c.id, c.name
FROM customers c
WHERE c.id NOT IN (SELECT customer_id FROM orders);

NULL tuzağı

orders.customer_id kolonunda tek bir NULL varsa 3. sorgu hiç satır döndürmez.

Sebep SQL'in üç değerli mantığıdır: x NOT IN (1, 2, NULL) ifadesi x <> 1 AND x <> 2 AND x <> NULL demektir. x <> NULL sonucu UNKNOWN olduğu için tüm ifade asla TRUE olmaz.

SELECT 5 NOT IN (1, 2, NULL);   -- NULL (true değil)
SELECT 5 NOT IN (1, 2);         -- true

NOT EXISTS ise yalnızca eşleşen bir satır olup olmadığına bakar, NULL'dan etkilenmez.

Performans

Modern optimizer'lar (PostgreSQL, SQL Server, MySQL 8) NOT EXISTS ve LEFT JOIN ... IS NULL'ı genelde aynı anti-join planına çevirir. orders.customer_id üzerinde index olması kritik. NOT IN ise NULL olasılığı yüzünden çoğu zaman bu optimizasyonu alamaz.

Kural: alt sorgu NULL içerebilecekse NOT IN kullanmayın; ya NOT EXISTS yazın ya da alt sorguya WHERE customer_id IS NOT NULL ekleyin.

  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