Subquery Nedir? WHERE'da Subquery
Giriş — Sorgu İçinde Sorgu
Bazen bir soruyu cevaplamak için önce başka bir soruyu cevaplaman gerekir: "Ortalama fiyattan pahalı ürünleri göster" — önce ortalamayı hesapla, sonra o değerden büyük olanları filtrele. İşte subquery (alt sorgu) bir sorgunun içinde çalışan başka bir sorgudur.
🎯 Analoji: Bir soruyu cevaplamak için ansiklopedi açıyorsun, orada başka bir kavrama atıfta bulunuyor, onu da araştırıyorsun. Subquery, SQL'in "iç içe arama" mekanizmasıdır.
Temel Subquery — WHERE'da Kullanım
-- Ortalama fiyattan pahalı ürünler
SELECT product_name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products);
-- Subquery önce çalışır: AVG(price) = 13009.99
-- Sonra dış sorgu: price > 13009.99 olan ürünler
-- En son sipariş veren müşteriyi bul
SELECT first_name, last_name
FROM customers
WHERE customer_id = (
SELECT customer_id FROM orders ORDER BY order_date DESC LIMIT 1
);
-- En pahalı ürünü bul
SELECT product_name, price
FROM products
WHERE price = (SELECT MAX(price) FROM products);IN ile Subquery — Birden Fazla Değer
-- Sipariş vermiş müşteriler
SELECT first_name, last_name
FROM customers
WHERE customer_id IN (SELECT DISTINCT customer_id FROM orders);
-- Elektronik kategorisindeki (ve alt kategoriler) ürünler
SELECT product_name, price
FROM products
WHERE category_id IN (
SELECT category_id FROM categories
WHERE category_name IN ('Elektronik', 'Bilgisayar', 'Telefon')
);
-- Ocak ayında sipariş edilen ürünler
SELECT product_name
FROM products
WHERE product_id IN (
SELECT DISTINCT oi.product_id
FROM order_items oi
INNER JOIN orders o ON oi.order_id = o.order_id
WHERE MONTH(o.order_date) = 1 AND YEAR(o.order_date) = 2024
);NOT IN ile Subquery
-- Hiç sipariş vermemiş müşteriler
SELECT first_name, last_name
FROM customers
WHERE customer_id NOT IN (
SELECT DISTINCT customer_id FROM orders
);⚠️ Dikkat: NOT IN subquery'den NULL dönerse hiçbir satır dönmez! Çünkü
x NOT IN (1, 2, NULL)her zaman UNKNOWN döndürür. ``sql -- Güvenli yol: WHERE koşuluyla NULL'ları ele WHERE customer_id NOT IN ( SELECT customer_id FROM orders WHERE customer_id IS NOT NULL ); -- Veya NOT EXISTS kullan (NULL-safe)``
Karşılaştırma Operatörleriyle Subquery
-- Ortalamadan pahalı
WHERE price > (SELECT AVG(price) FROM products)
-- Minimum fiyattan ucuz olmayan
WHERE price >= (SELECT MIN(price) FROM products WHERE category_id = 2)
-- Belirli bir müşterinin sipariş sayısından fazla sipariş verenler
SELECT customer_id, COUNT(*) AS cnt
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > (
SELECT COUNT(*) FROM orders WHERE customer_id = 1
);Gerçek Dünya Örneği
-- Bu ay ortalamasının üstünde sipariş veren müşteriler
SELECT c.first_name, c.last_name, SUM(o.total_amount) AS total
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
WHERE MONTH(o.order_date) = MONTH(NOW()) AND YEAR(o.order_date) = YEAR(NOW())
GROUP BY c.customer_id, c.first_name, c.last_name
HAVING SUM(o.total_amount) > (
SELECT AVG(monthly_total) FROM (
SELECT SUM(total_amount) AS monthly_total
FROM orders
WHERE MONTH(order_date) = MONTH(NOW()) AND YEAR(order_date) = YEAR(NOW())
GROUP BY customer_id
) AS monthly_avgs
);Sıkça Yapılan Hatalar
Scalar subquery birden fazla satır döndürür:
WHERE price = (SELECT price FROM products)hata verir — tek satır bekleniyor. IN kullan veya LIMIT ekle.NOT IN ve NULL: NULL değer subquery sonucundaysa NOT IN çalışmaz. NOT EXISTS tercih et.
Performans: Correlated subquery her satır için çalışır — büyük tablolarda yavaş. JOIN'e çevirmeyi düşün.
Özet
Subquery bir sorgunun içinde çalışan başka bir sorgudur
WHERE'da =, >, <, IN, NOT IN ile kullanılır
Scalar subquery tek değer, IN subquery çoklu değer döndürür
NOT IN ile NULL dikkat — NOT EXISTS daha güvenli
Subquery parantez içine yazılır ve ilk çalışan odur
AI Asistan
Sorularını yanıtlamaya hazır