subquery mysql nested select | java php laravel linux mysql sql bootstrap html css query java php laravel linux mysql sql bootstrap html css query: subquery mysql nested select

Wednesday, April 8, 2026

subquery mysql nested select

Beranda Tutorial MySQL Artikel 23

๐Ÿ”ด Level Lanjutan ๐Ÿ—ƒ️ Subquery & Nested SELECT ⏱️ ~10 Menit Baca ๐Ÿ“˜ Artikel 23 / 28

Query di Dalam Query: Subquery dan Nested SELECT

6
Jenis Subquery
8
Contoh Query
10
Menit Baca
3
Tabel Data

Pernah gak kamu lagi belanja online, terus kepikiran: "Produk apa sih yang paling laris dari semua kategori yang tersedia?" — Untuk menjawab pertanyaan kayak gitu, kamu butuh dua langkah: pertama cari daftar kategori, baru cari produk terlaris di tiap kategori. Di dunia MySQL, proses dua-langkah inilah yang diselesaikan oleh subquery MySQL nested SELECT — sebuah query yang berjalan di dalam query lain.

Selamat datang di Artikel ke-23 dari 28 dalam seri Belajar Query SQL MySQL! Di artikel ini, kita bakal kupas tuntas teknik subquery MySQL nested SELECT — mulai dari konsep dasarnya, cara kerjanya di klausa WHERE, FROM, dan SELECT, hingga perbandingannya dengan JOIN. Kalau kamu sudah melewati JOIN di artikel-artikel sebelumnya, subquery ini akan terasa seperti senjata baru yang bikin SQL-mu jauh lebih ekspresif.

Semua contoh menggunakan studi kasus toko online dengan tabel produk, pelanggan, dan pesanan — biar langsung relate dan bisa kamu praktikkan.

๐Ÿ’ก Fakta Menarik

Menurut survei Stack Overflow Developer Survey, subquery adalah salah satu fitur SQL yang paling sering "takut dipakai" oleh developer junior — padahal lebih dari 70% query analitik di aplikasi e-commerce nyata menggunakan subquery dalam satu bentuk atau lainnya. Setelah artikel ini, kamu nggak akan takut lagi!

1. Apa Itu Subquery? Analogi & Konsep Dasar

Bayangkan kamu minta tolong teman: "Beliin aku minum yang sama kayak yang dibeli si Budi kemarin." Sebelum bisa beliin, temanmu harus tanya dulu ke Budi beli apa — itu adalah query dalam query. Di MySQL, konsepnya persis sama: subquery adalah SELECT yang dieksekusi lebih dulu, hasilnya dipakai oleh query luar (outer query).

Subquery selalu ditulis di dalam tanda kurung ( ) dan bisa muncul di klausa WHERE, FROM, maupun SELECT.

๐Ÿ“‹ Sintaks Dasar Subquery
-- Struktur umum subquery di WHERE
SELECT kolom1, kolom2
FROM tabel_luar
WHERE kolom_x operator (
    -- Ini adalah subquery (inner query)
    SELECT kolom_y
    FROM tabel_dalam
    WHERE kondisi_tertentu
);

-- Operator bisa berupa: =, >, <, IN, NOT IN, EXISTS, ANY, ALL

๐Ÿ” Contoh: Tampilkan produk dengan harga di atas rata-rata

-- Tampilkan produk yang harganya di atas rata-rata semua produk
SELECT nama_produk, harga, kategori
FROM produk
WHERE harga > (
    SELECT AVG(harga)   -- subquery: hitung rata-rata harga
    FROM produk
);
nama_produk harga kategori
Laptop ProMax 15 Rp 12.500.000 Elektronik
Smartphone UltraX Rp 8.750.000 Elektronik
Kamera Mirrorless Z Rp 9.200.000 Elektronik

* AVG(harga) = Rp 5.300.000 — hanya produk di atas nilai ini yang muncul.

✅ Tip Praktis

Subquery di klausa WHERE yang mengembalikan satu nilai (scalar subquery) paling aman untuk pemula. Pastikan inner query tidak mengembalikan lebih dari satu baris jika kamu menggunakan operator =.

2. Subquery dengan IN dan NOT IN — Filter Berdasarkan Daftar Dinamis

Kalau = hanya cocok untuk subquery yang mengembalikan satu nilai, operator IN adalah sahabatmu ketika subquery menghasilkan banyak baris. Analoginya: kamu punya daftar nama teman yang sudah RSVP ke acaramu, lalu kamu mau cari data lengkap mereka di buku kontak — itulah IN.

๐Ÿ” Contoh: Tampilkan pelanggan yang pernah memesan produk kategori "Elektronik"

-- Cari ID produk Elektronik dulu, lalu cari pelanggan yang memesannya
SELECT nama, email
FROM pelanggan
WHERE id_pelanggan IN (
    SELECT DISTINCT id_pelanggan   -- subquery: ambil ID pelanggan
    FROM pesanan
    WHERE id_produk IN (
        SELECT id_produk           -- nested subquery: ID produk Elektronik
        FROM produk
        WHERE kategori = 'Elektronik'
    )
);
nama email
Andi Saputra andi@example.com
Rina Dewi rina@example.com
Budi Santoso budi@example.com

๐Ÿ” Contoh NOT IN: Pelanggan yang BELUM pernah pesan sama sekali

-- Pelanggan yang tidak ada di tabel pesanan sama sekali
SELECT nama, email
FROM pelanggan
WHERE id_pelanggan NOT IN (
    SELECT DISTINCT id_pelanggan
    FROM pesanan
    WHERE id_pelanggan IS NOT NULL  -- PENTING: handle NULL!
);
⚠️ Peringatan Penting

Saat menggunakan NOT IN, kalau subquery-nya mengembalikan satu saja nilai NULL, keseluruhan query akan mengembalikan result kosong! Selalu tambahkan WHERE kolom IS NOT NULL di dalam subquery-mu.

3. Subquery di Klausa FROM — Derived Table (Tabel Sementara)

Nah, ini yang agak bikin pusing tapi super powerful. Subquery bisa dipakai sebagai sumber data di klausa FROM — seolah-olah subquery itu adalah tabel sungguhan. Ini disebut derived table. Analoginya: kamu bikin catatan coretan dulu di kertas baru, lalu kertas itu kamu jadikan sumber data untuk laporan resmi.

Derived table wajib diberi alias — MySQL tidak akan mengizinkan tanpanya.

๐Ÿ” Contoh: Tampilkan pelanggan dengan total belanja di atas rata-rata

-- Langkah 1 (inner): Hitung total belanja per pelanggan
-- Langkah 2 (outer): Filter yang di atas rata-rata
SELECT p.nama, ringkasan.total_belanja
FROM pelanggan p
JOIN (
    SELECT id_pelanggan,
           SUM(total_harga) AS total_belanja   -- subquery sebagai tabel
    FROM pesanan
    GROUP BY id_pelanggan
) AS ringkasan                                 -- alias WAJIB ada!
  ON p.id_pelanggan = ringkasan.id_pelanggan
WHERE ringkasan.total_belanja > (
    SELECT AVG(total_harga) FROM pesanan
)
ORDER BY ringkasan.total_belanja DESC;
nama total_belanja
Rina Dewi Rp 23.450.000
Budi Santoso Rp 18.200.000
Andi Saputra Rp 15.900.000
✅ Insight dari Lapangan

Derived table di klausa FROM adalah alternatif elegan dari CTE (WITH ... AS). Untuk query yang pendek, derived table lebih ringkas. Untuk query yang panjang dan perlu dibaca ulang, gunakan CTE agar lebih mudah di-debug.

4. Subquery di Klausa SELECT — Kolom yang Dihitung Dinamis

Selain WHERE dan FROM, subquery juga bisa masuk langsung ke daftar kolom di SELECT. Hasilnya berupa kolom kalkulasi yang dihitung per baris. Ini disebut correlated subquery karena inner query mengacu pada nilai dari outer query (berjalan per baris).

๐Ÿ” Contoh: Tampilkan setiap produk beserta jumlah kali dipesan

-- Correlated subquery: inner query mengacu ke p.id_produk (outer)
SELECT
    nama_produk,
    harga,
    (
        SELECT COUNT(*)
        FROM pesanan ps
        WHERE ps.id_produk = p.id_produk   -- korelasi ke outer query
    ) AS jumlah_pesanan
FROM produk p
ORDER BY jumlah_pesanan DESC;
nama_produk harga jumlah_pesanan
Smartphone UltraX Rp 8.750.000 47
Headphone BassMax Rp 450.000 38
Laptop ProMax 15 Rp 12.500.000 22
Charger Turbo 65W Rp 175.000 15
⚠️ Perhatikan Performa

Correlated subquery di klausa SELECT dieksekusi satu kali per baris dari outer query. Jika tabel produk punya 10.000 baris, subquery dijalankan 10.000 kali! Untuk dataset besar, lebih efisien menggunakan LEFT JOIN + GROUP BY atau derived table.

๐Ÿงช Panduan Praktikum: Subquery dari Nol

1

Siapkan Tabel & Data Contoh

CREATE TABLE produk (
  id_produk INT PRIMARY KEY AUTO_INCREMENT,
  nama_produk VARCHAR(100),
  harga DECIMAL(15,2),
  kategori VARCHAR(50)
);

CREATE TABLE pelanggan (
  id_pelanggan INT PRIMARY KEY AUTO_INCREMENT,
  nama VARCHAR(100),
  email VARCHAR(100)
);

CREATE TABLE pesanan (
  id_pesanan INT PRIMARY KEY AUTO_INCREMENT,
  id_pelanggan INT,
  id_produk INT,
  total_harga DECIMAL(15,2),
  tanggal DATE
);
2

Mulai dengan Subquery Sederhana (Scalar)

Coba cari produk termahal menggunakan subquery:

SELECT nama_produk, harga
FROM produk
WHERE harga = (SELECT MAX(harga) FROM produk);
3

Coba Subquery dengan IN

Tampilkan produk yang pernah ada dalam pesanan:

SELECT nama_produk, harga
FROM produk
WHERE id_produk IN (
    SELECT DISTINCT id_produk
    FROM pesanan
    WHERE id_produk IS NOT NULL
);
4

Tantangan: Buat Nested Subquery 2 Level

Cari nama pelanggan yang memesan produk kategori "Elektronik" dengan harga di atas 5 juta:

SELECT nama FROM pelanggan
WHERE id_pelanggan IN (
    SELECT DISTINCT id_pelanggan FROM pesanan
    WHERE id_produk IN (
        SELECT id_produk FROM produk
        WHERE kategori = 'Elektronik'
          AND harga > 5000000
    )
);

๐Ÿ“Š Perbandingan: Subquery vs JOIN

Pertanyaan klasik: kapan pakai subquery, kapan pakai JOIN? Ini perbandingan singkatnya:

Aspek Subquery JOIN
Keterbacaan ✅ Lebih mudah dibaca untuk logika bertingkat ⚡ Lebih ringkas untuk relasi sederhana
Performa ⚠️ Correlated subquery bisa lambat di data besar ✅ Umumnya lebih cepat dengan index yang tepat
Fleksibilitas ✅ Bisa di WHERE, FROM, SELECT sekaligus ⚡ Hanya di FROM/ON clause
Agregasi bertingkat ✅ Ideal untuk "max dari max" atau "avg dari sum" ⚠️ Butuh derived table atau CTE
Duplikasi baris ✅ Tidak menghasilkan duplikat ⚠️ Bisa menghasilkan duplikat jika tidak pakai DISTINCT
Kapan digunakan? Filter dinamis, agregasi bertingkat, derived table Gabung data dari dua tabel atau lebih secara langsung
๐Ÿ’ก Tips Praktis #1 — Debug Subquery Seperti Pro

Saat subquery-mu tidak menghasilkan output yang diharapkan, jalankan inner query terlebih dahulu secara terpisah. Copy bagian dalam kurung, eksekusi sendiri, dan periksa hasilnya. Ini cara tercepat untuk isolasi bug tanpa perlu menebak-nebak.

๐Ÿ’ก Tips Praktis #2 — Gunakan EXISTS untuk Performa Lebih Baik

Ketika kamu hanya perlu mengecek apakah ada data yang cocok (bukan mengambil nilainya), gunakan EXISTS — ini lebih efisien dari IN pada data besar karena MySQL berhenti mencari begitu satu baris ditemukan.

-- EXISTS: lebih cepat untuk "apakah ada pesanan?"
SELECT nama FROM pelanggan p
WHERE EXISTS (
    SELECT 1 FROM pesanan ps
    WHERE ps.id_pelanggan = p.id_pelanggan
);

๐ŸŽฏ Kesimpulan

  • Subquery MySQL nested SELECT adalah query yang berjalan di dalam query lain, dieksekusi terlebih dahulu.
  • Bisa dipakai di klausa WHERE (filter), FROM (derived table), dan SELECT (kolom kalkulasi).
  • Operator IN/NOT IN cocok untuk subquery multi-baris; = untuk scalar.
  • Selalu hati-hati dengan NULL di NOT IN — tambahkan filter IS NOT NULL.
  • Untuk performa optimal di data besar, pertimbangkan EXISTS, JOIN, atau CTE.
  • Debug dengan cara menjalankan inner query secara terpisah terlebih dahulu.

Subquery ibarat superkekuatan di gudang senjata SQL-mu — memang butuh sedikit waktu untuk terbiasa, tapi begitu kamu menguasainya, query yang dulu terasa mustahil jadi terasa natural. Seri kita hampir selesai — 5 artikel lagi menuju finish line! ๐Ÿš€

Artikel Berikutnya dalam Seri

Artikel 24: Common Table Expressions (CTE) dengan WITH

Subquery sudah kamu kuasai — sekarang saatnya naik level ke CTE! Pelajari cara menulis query kompleks yang jauh lebih mudah dibaca dan di-debug menggunakan klausa WITH di MySQL 8+.

Baca Artikel 24 →
#MySQL #SQL #Database #Query #Tutorial #subquery MySQL nested SELECT #BelajarSQL #NestedSELECT

No comments:

Post a Comment

saifiahmada.com adalah blog belajar programming Indonesia, membahas lengkap materi bahasa pemrograman: code HTML, CSS, Bootstrap, Desain, PHP, MySQL, coding Java, Query, SQL, dan dunia linux