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); -- trueNOT 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.
İ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.