- Home
- Kelas Belajar
- SQL Lanjutan: JOIN, Subquery, GROUP BY & Desain Skema Database Production-Ready
Kelas ini dirancang untuk kamu yang sudah paham dasar SQL dan siap naik level ke penggunaan yang lebih realistis di dunia kerja. Kamu akan belajar menguasai JOIN kompleks, subquery, agregasi data dengan GROUP BY, hingga merancang skema database ternormalisasi dengan baik, lengkap dengan best practice dan kesalahan umum yang harus dihindari. Di akhir kelas, kamu akan membangun sebuah skema database dan query kompleks untuk studi kasus nyata.
Di kelas SQL dasar, kamu mungkin cukup menjalankan query sederhana di satu tabel kecil dan hasilnya langsung terasa cepat. Namun begitu masuk ke JOIN kompleks, subquery bertingkat, dan agregasi data dalam jumlah besar, performa query menjadi masalah nyata. Modul ini menyiapkan environment yang bisa kamu pakai untuk menguji, mengukur, dan mendiagnosis query — bukan sekadar menjalankannya.
Kita akan menyiapkan database dengan data yang cukup besar (bukan 5 baris contoh), mengaktifkan tools analisis performa seperti EXPLAIN, dan menyiapkan struktur project yang rapi untuk latihan sepanjang kelas ini.
Kelas ini menggunakan PostgreSQL karena mendukung fitur SQL lanjutan secara lengkap (window functions, CTE recursive, JSONB, dsb) dan tools analisis query-nya (EXPLAIN ANALYZE) sangat informatif. Jika kamu terbiasa dengan MySQL, sebagian besar konsep tetap berlaku, tapi syntax tertentu (terutama window function dan beberapa subquery) bisa sedikit berbeda.
Daripada instalasi manual yang rawan konflik versi, gunakan Docker agar environment konsisten di semua device:
docker run --name pg-lanjutan \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=admin123 \
-e POSTGRES_DB=toko_online \
-p 5432:5432 \
-d postgres:16
Cek apakah container berjalan dengan docker ps. Untuk masuk ke shell psql:
docker exec -it pg-lanjutan psql -U admin -d toko_online
Untuk kelas ini, disarankan pakai DBeaver (gratis, cross-platform) karena punya fitur visualisasi EXPLAIN plan berupa diagram, memudahkan kamu membaca query planner. Tapi kamu tetap perlu terbiasa dengan psql di terminal karena di lingkungan production, akses GUI sering tidak tersedia — kamu akan sering SSH ke server dan menjalankan query lewat CLI.
Query yang cepat di 100 baris data bisa jadi sangat lambat di 1 juta baris — dan justru di situlah letak pembelajaran performa yang sesungguhnya. Kita akan pakai skema toko_online yang nanti dipakai konsisten sampai proyek akhir (studi kasus e-commerce di modul 12).
CREATE TABLE pelanggan (
id SERIAL PRIMARY KEY,
nama VARCHAR(100),
kota VARCHAR(50),
dibuat_pada TIMESTAMP DEFAULT now()
);
CREATE TABLE produk (
id SERIAL PRIMARY KEY,
nama_produk VARCHAR(100),
kategori VARCHAR(50),
harga NUMERIC(10,2)
);
CREATE TABLE pesanan (
id SERIAL PRIMARY KEY,
pelanggan_id INT REFERENCES pelanggan(id),
dibuat_pada TIMESTAMP DEFAULT now()
);
CREATE TABLE detail_pesanan (
id SERIAL PRIMARY KEY,
pesanan_id INT REFERENCES pesanan(id),
produk_id INT REFERENCES produk(id),
jumlah INT,
harga_satuan NUMERIC(10,2)
);
Untuk mengisi data dalam jumlah besar tanpa menulis manual satu-satu, gunakan fungsi generate_series milik PostgreSQL — teknik ini juga akan sering kamu pakai saat butuh data dummy untuk testing performa:
INSERT INTO pelanggan (nama, kota)
SELECT 'Pelanggan ' || i,
(ARRAY['Jakarta','Bandung','Surabaya','Medan'])[floor(random()*4+1)]
FROM generate_series(1, 5000) AS i;
INSERT INTO produk (nama_produk, kategori, harga)
SELECT 'Produk ' || i,
(ARRAY['Elektronik','Fashion','Makanan'])[floor(random()*3+1)],
(random()*500000)::numeric(10,2)
FROM generate_series(1, 1000) AS i;
INSERT INTO pesanan (pelanggan_id)
SELECT floor(random()*5000+1)
FROM generate_series(1, 20000) AS i;
INSERT INTO detail_pesanan (pesanan_id, produk_id, jumlah, harga_satuan)
SELECT floor(random()*20000+1), floor(random()*1000+1),
floor(random()*5+1), (random()*500000)::numeric(10,2)
FROM generate_series(1, 60000) AS i;
Dengan skala ribuan hingga puluhan ribu baris seperti ini, perbedaan performa antar strategi query mulai terasa — inilah kondisi yang lebih dekat dengan realita production dibanding contoh 5-10 baris di kelas dasar.
EXPLAIN ANALYZE adalah tool paling penting yang akan kamu pakai berulang kali sepanjang kelas ini. Ia menunjukkan bagaimana PostgreSQL benar-benar mengeksekusi query-mu, termasuk apakah ia memakai index, berapa lama tiap tahap dieksekusi, dan berapa baris yang diproses di tiap langkah.
EXPLAIN ANALYZE
SELECT p.nama, COUNT(o.id) AS total_pesanan
FROM pelanggan p
JOIN pesanan o ON o.pelanggan_id = p.id
GROUP BY p.nama;
Perhatikan bagian Seq Scan vs Index Scan pada hasil output. Seq Scan berarti PostgreSQL membaca seluruh tabel baris per baris — sering menjadi tanda bahwa index belum optimal, topik yang akan kita bahas lebih dalam saat masuk ke best practice production (modul 10).
Agar konsisten, simpan semua script SQL latihanmu dalam folder dengan penamaan berurutan, misalnya:
01_setup_schema.sql02_seed_data.sql03_join_dasar.sql04_subquery.sqlKebiasaan ini meniru praktik migration file di dunia kerja nyata, di mana perubahan skema database harus terdokumentasi dan bisa dijalankan ulang secara berurutan.
Bayangkan kamu baru bergabung sebagai data analyst di sebuah startup e-commerce. Tim meminta kamu menyiapkan database lokal yang merepresentasikan data produksi agar kamu bisa menguji query laporan penjualan tanpa mengganggu database asli.
Langkah yang bisa kamu coba sendiri:
toko_online.pelanggan, produk, pesanan, detail_pesanan) sesuai skema di atas.generate_series, tapi ubah jumlah barisnya menjadi 10x lebih besar dari contoh untuk melihat efeknya terhadap waktu eksekusi.EXPLAIN ANALYZE:
SELECT pr.kategori, SUM(d.jumlah * d.harga_satuan) AS total_penjualan
FROM detail_pesanan d
JOIN produk pr ON pr.id = d.produk_id
GROUP BY pr.kategori
ORDER BY total_penjualan DESC;
Execution Time) sebelum dan sesudah kamu menambahkan index berikut, lalu jalankan ulang query yang sama:
CREATE INDEX idx_detail_produk ON detail_pesanan(produk_id);
Simpan hasil observasi ini — kamu akan membutuhkannya sebagai baseline pembanding saat mempelajari JOIN kompleks dan window function di modul-modul berikutnya. Environment yang sudah kamu siapkan di modul ini akan terus dipakai sampai proyek akhir, jadi pastikan setup-nya berjalan stabil sebelum lanjut ke materi selanjutnya.
Modul baru ditambahkan secara berkala hingga kelas ini lengkap. Simpan halaman ini dan kembali lagi untuk lanjut belajar.