Scalar, Row ve Table Subquery
Giriş — Subquery'nin Üç Farklı Boyutu
Subquery'ler döndürdükleri verinin şekline göre üç türe ayrılır. Her tür farklı yerlerde kullanılır.
1. Scalar Subquery — Tek Değer
Tek satır, tek sütun döndürür. Tek bir değer (sayı, string, tarih):
-- SELECT'te scalar subquery (hesaplanmış sütun)
SELECT product_name, price,
price - (SELECT AVG(price) FROM products) AS diff_from_avg,
ROUND(price / (SELECT MAX(price) FROM products) * 100, 1) AS pct_of_max
FROM products
ORDER BY price DESC;
-- WHERE'da scalar subquery
SELECT * FROM products
WHERE price = (SELECT MAX(price) FROM products);
-- UPDATE'te scalar subquery
UPDATE orders
SET total_amount = (
SELECT SUM(quantity * unit_price * (1 - discount_percent/100))
FROM order_items WHERE order_items.order_id = orders.order_id
)
WHERE order_id = 1;⚠️ Scalar subquery birden fazla satır döndürürse HATA alırsın. LIMIT 1 ekle veya aggregate fonksiyon kullan.
2. Row Subquery — Tek Satır, Çoklu Sütun
Tek satır ama birden fazla sütun döndürür:
-- En pahalı ürünün adını ve fiyatını tek sorguyla bul
SELECT * FROM products
WHERE (category_id, price) = (
SELECT category_id, MAX(price)
FROM products
WHERE category_id = 2
GROUP BY category_id
);
-- Birden fazla sütun karşılaştırması
SELECT * FROM order_items
WHERE (order_id, product_id) = (
SELECT order_id, product_id FROM order_items ORDER BY unit_price DESC LIMIT 1
);3. Table Subquery — Çoklu Satır, Çoklu Sütun
Bir tablo gibi davranır. Genellikle FROM'da veya IN ile kullanılır:
-- FROM'da (derived table / türetilmiş tablo)
SELECT city, avg_order
FROM (
SELECT c.city, ROUND(AVG(o.total_amount), 2) AS avg_order
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.city
) AS city_orders
WHERE avg_order > 10000;
-- IN ile
SELECT * FROM customers
WHERE customer_id IN (
SELECT customer_id FROM orders GROUP BY customer_id HAVING COUNT(*) > 2
);💡 FROM'daki subquery'ye alias vermek zorunludur (
AS city_orders).
Karşılaştırma Tablosu
| Tür | Döndürdüğü | Kullanıldığı Yer | Örnek |
|---|---|---|---|
| Scalar | 1 değer | SELECT, WHERE, HAVING | (SELECT AVG(price) FROM products) |
| Row | 1 satır, N sütun | WHERE (çoklu sütun karşılaştırma) | WHERE (a, b) = (SELECT ...) |
| Table | N satır, M sütun | FROM, IN, EXISTS | FROM (SELECT ...) AS t |
Özet
Scalar: tek değer → SELECT, WHERE, SET'te kullanılır
Row: tek satır, çoklu sütun → çoklu sütun karşılaştırmasında
Table: çoklu satır → FROM'da derived table, IN listesi olarak
FROM'daki subquery'ye alias zorunlu
Scalar subquery birden fazla satır döndürürse hata alırsın
AI Asistan
Sorularını yanıtlamaya hazır