FROM'da Subquery (Derived Table)
Giriş — Geçici Tablo Oluşturmadan Ara Sonuçlar
FROM'da subquery kullanmak, sorgu sonucunu geçici bir tablo gibi kullanmana olanak tanır. Buna derived table (türetilmiş tablo) denir. Karmaşık hesaplamaları adımlara bölerek daha okunabilir sorgular yazmanı sağlar.
Temel Kullanım
-- Müşteri sipariş istatistiklerini hesapla, sonra filtrele
SELECT customer_name, order_count, total_spent
FROM (
SELECT
CONCAT(c.first_name, ' ', c.last_name) AS customer_name,
COUNT(o.order_id) AS order_count,
COALESCE(SUM(o.total_amount), 0) AS total_spent
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name
) AS customer_stats -- ← Alias ZORUNLU!
WHERE total_spent > 5000
ORDER BY total_spent DESC;Neden derived table? WHERE'da aggregate sonucu filtrelemek normalde HAVING ile yapılır ama bazen derived table daha okunabilir. Ayrıca birden fazla aggregate sonucunu kullanarak yeni hesaplamalar yapabilirsin.
İç İçe Hesaplamalar
-- Ortalama sipariş tutarının ortalaması (iç içe aggregate)
SELECT ROUND(AVG(avg_order), 2) AS overall_avg_order
FROM (
SELECT customer_id, AVG(total_amount) AS avg_order
FROM orders
GROUP BY customer_id
) AS customer_avgs;
-- En yüksek müşteri bazlı gelirle en düşük arasındaki fark
SELECT
MAX(total_spent) AS max_customer_revenue,
MIN(total_spent) AS min_customer_revenue,
MAX(total_spent) - MIN(total_spent) AS revenue_gap
FROM (
SELECT customer_id, SUM(total_amount) AS total_spent
FROM orders
GROUP BY customer_id
) AS customer_revenues;Birden Fazla Derived Table
-- Top müşteriler vs ortalama karşılaştırması
SELECT
cs.customer_name,
cs.total_spent,
avgs.overall_avg,
cs.total_spent - avgs.overall_avg AS diff_from_avg
FROM (
SELECT CONCAT(c.first_name, ' ', c.last_name) AS customer_name,
c.customer_id,
SUM(o.total_amount) AS total_spent
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name
) AS cs
CROSS JOIN (
SELECT AVG(total_amount) AS overall_avg FROM orders
) AS avgs
WHERE cs.total_spent > avgs.overall_avg;Derived Table vs CTE
Derived table iç içe yazıldığında okunması zorlaşır. CTE (Common Table Expression — B12'de göreceğiz) daha okunabilir bir alternatiftir:
-- Derived table (iç içe)
SELECT * FROM (SELECT * FROM (SELECT ...) AS t1) AS t2;
-- CTE (sıralı, okunabilir) — B12'de detaylı göreceğiz
WITH customer_stats AS (SELECT ...),
category_stats AS (SELECT ...)
SELECT * FROM customer_stats JOIN category_stats ON ...;Özet
Derived table = FROM'da subquery, geçici tablo gibi davranır
Alias vermek zorunludur (
AS isim)İç içe aggregate hesaplamalar için idealdir
Birden fazla derived table CROSS JOIN ile birleştirilebilir
Karmaşık derived table'lar CTE ile daha okunabilir yazılabilir
AI Asistan
Sorularını yanıtlamaya hazır