Subqueries: Query di Dalam Query 📦
Halo SQL Explorers! 👋 Di materi sebelumnya kita udah belajar JOIN yang kompleks. Sekarang kita bakal belajar subquery, cara keren buat bikin query yang lebih canggih!
Apa itu Subquery? 🤔
Subquery itu “query di dalam query”. Bayangkan:
- Kamu mau tau produk yang harganya di atas rata-rata
- Kamu perlu cari rata-rata dulu, baru filter produknya
- Ini bisa dipake buat analisis yang lebih kompleks!
Data yang Kita Pake 📊
Kita tetep pake database toko online kita, tapi kita bakal liat dari sudut pandang yang beda:
-- Liat rata-rata pembelian per customer
SELECT
c.nama,
(SELECT AVG(oi.quantity * oi.price)
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.customer_id = c.id) as rata_rata_belanja
FROM customers c;
-- Hasilnya:
+------+------------------+
| nama | rata_rata_belanja|
+------+------------------+
| Budi | 10000000 |
| Ani | 275000 |
| Caca | 50000 |
| Dodi | NULL |
+------+------------------+
Jenis-jenis Subquery 🔄
1. Scalar Subquery
Subquery yang ngasih SATU nilai:
-- Cari produk yang harganya di atas rata-rata
SELECT nama, harga
FROM products
WHERE harga > (
SELECT AVG(harga)
FROM products
);
-- Hitung persentase harga dari total
SELECT
nama,
harga,
(harga / (SELECT SUM(harga) FROM products) * 100) as persen_total
FROM products;
2. List Subquery
Subquery yang ngasih BANYAK nilai:
-- Cari produk yang pernah dibeli
SELECT nama
FROM products
WHERE id IN (
SELECT DISTINCT product_id
FROM order_items
);
-- Cari customer yang belum pernah order
SELECT nama
FROM customers
WHERE id NOT IN (
SELECT DISTINCT customer_id
FROM orders
);
3. Table Subquery
Subquery yang ngasih TABEL sementara:
-- Analisis penjualan per kategori
SELECT
cat.nama as kategori,
sales.total_penjualan
FROM categories cat
JOIN (
SELECT
p.category_id,
SUM(oi.quantity * oi.price) as total_penjualan
FROM products p
JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.category_id
) sales ON cat.id = sales.category_id;
4. Correlated Subquery
Subquery yang TERHUBUNG ke query utama:
-- Cari produk termahal di tiap kategori
SELECT p1.nama, p1.category_id, p1.harga
FROM products p1
WHERE p1.harga = (
SELECT MAX(p2.harga)
FROM products p2
WHERE p2.category_id = p1.category_id
);
-- Cari customer dengan order di atas rata-rata
SELECT c.nama
FROM customers c
WHERE (
SELECT AVG(oi.quantity * oi.price)
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.customer_id = c.id
) > (
SELECT AVG(oi.quantity * oi.price)
FROM order_items oi
);
Tips Pake Subquery 💡
Pilih yang Tepat: JOIN vs Subquery
-- Pake JOIN kalo perlu data dari tabel lain SELECT c.nama, o.tanggal FROM customers c JOIN orders o ON c.id = o.customer_id; -- Pake subquery kalo perlu perhitungan SELECT nama, (SELECT COUNT(*) FROM orders WHERE customer_id = c.id) as total_order FROM customers c;Perhatiin Performa
-- Subquery yang berat SELECT * FROM products WHERE category_id IN ( SELECT id FROM categories WHERE nama LIKE '%Electronics%' ); -- Lebih cepet pake JOIN SELECT p.* FROM products p JOIN categories c ON p.category_id = c.id WHERE c.nama LIKE '%Electronics%';Pake Alias yang Jelas
-- Bikin query lebih mudah dibaca SELECT p1.nama, (SELECT MAX(p2.harga) FROM products p2 WHERE p2.category_id = p1.category_id) as max_harga FROM products p1;
Latihan Subquery 🎯
- Analisis Customer Premium
-- Cari customer yang total belanjanya di atas rata-rata
SELECT
c.nama,
(SELECT SUM(oi.quantity * oi.price)
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.customer_id = c.id) as total_belanja
FROM customers c
HAVING total_belanja > (
SELECT AVG(subtotal)
FROM (
SELECT o.customer_id,
SUM(oi.quantity * oi.price) as subtotal
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.customer_id
) avg_spending
);
- Produk Terlaris per Kategori
-- Cari produk dengan penjualan tertinggi di tiap kategori
SELECT
c.nama as kategori,
p.nama as produk,
sales.total_terjual
FROM products p
JOIN categories c ON p.category_id = c.id
JOIN (
SELECT
product_id,
SUM(quantity) as total_terjual
FROM order_items
GROUP BY product_id
) sales ON p.id = sales.product_id
WHERE (p.category_id, sales.total_terjual) IN (
SELECT
p2.category_id,
MAX(oi2.quantity)
FROM products p2
JOIN order_items oi2 ON p2.id = oi2.product_id
GROUP BY p2.category_id
);
Preview Materi Selanjutnya 🎯
Di materi aggregate functions kita bakal belajar:
- Fungsi COUNT, SUM, AVG
- Grouping data yang kompleks
- Window functions
- Dan masih banyak lagi! 🚀
Siap belajar lebih dalam? Yuk lanjut ke materi aggregate functions! 🎯