INNER JOIN SQL: Cara Kerja + Contoh Kasus Penjualan
TL;DR
INNER JOIN nggabungin dua tabel lewat kolom kunci yang sama, dan cuma nyisain baris yang ketemu pasangannya di kedua tabel. Baris yang gak punya pasangan langsung dibuang dari hasil, jadi jumlah baris hasil query bisa lebih sedikit dari tabel aslinya. Ini JOIN paling sering dipakai analis, biasanya buat nyambungin tabel transaksi ke tabel master produk atau pelanggan.
INNER JOIN nggabungin dua tabel lewat kolom kunci yang nilainya sama, dan cuma nyisain baris yang ketemu pasangannya di dua-duanya. Baris yang jomblo langsung dibuang dari hasil.
Ini JOIN yang paling sering kamu pakai sebagai analis. Tabel transaksi biasanya cuma nyimpen id_produk, bukan nama produknya. Nama produknya ada di tabel lain. INNER JOIN yang nyambungin dua-duanya.
Kalau kamu baru pertama kali ketemu JOIN, tenang. Query pertamanya cuma 4 baris.
Apa itu INNER JOIN di SQL?
INNER JOIN adalah operasi yang nyocokin baris dari dua tabel berdasarkan kolom kunci, terus nampilin baris yang cocok aja. Kalau satu baris di tabel kiri nggak nemu pasangan di tabel kanan, baris itu nggak muncul di hasil. Begitu juga sebaliknya.
Sintaks dasarnya:
SELECT kolom_yang_kamu_mau
FROM tabel_kiri
INNER JOIN tabel_kanan
ON tabel_kiri.kunci = tabel_kanan.kunci;
Kata INNER boleh dihapus. JOIN doang artinya sama persis dengan INNER JOIN di semua database populer. Tapi aku saranin tetap ditulis biar niat kamu jelas kebaca orang lain.
Gimana cara kerja INNER JOIN?
Database ngecek tiap baris di tabel kiri, terus nyari baris di tabel kanan yang nilai kuncinya sama. Ketemu, dua baris itu digabung jadi satu baris panjang. Nggak ketemu, barisnya dilewatin.
Aku pakai data Toko Berkah buat contohnya. Dua tabel: produk (master) dan penjualan (transaksi).
CREATE TABLE produk (
id_produk INTEGER PRIMARY KEY,
nama_produk TEXT,
kategori TEXT,
harga INTEGER
);
CREATE TABLE penjualan (
id_penjualan INTEGER PRIMARY KEY,
tanggal TEXT,
id_produk INTEGER,
qty INTEGER
);
INSERT INTO produk VALUES
(1,'Beras Premium 5kg','Sembako', 68500),
(2,'Minyak Goreng 2L','Sembako', 34750),
(3,'Gula Pasir 1kg','Sembako', 16250),
(4,'Kopi Bubuk 200g','Minuman', 21375),
(5,'Teh Celup 25s','Minuman', 12000);
INSERT INTO penjualan VALUES
(101,'2026-02-10', 1, 3),
(102,'2026-02-10', 3, 12),
(103,'2026-02-11', 2, 7),
(104,'2026-02-11', 4, 9),
(105,'2026-02-12', 1, 2),
(106,'2026-02-12', 9, 4);
Perhatiin baris terakhir. Transaksi 106 nyatet id_produk = 9, padahal produk nomor 9 nggak ada di tabel produk. Data kotor kayak gini normal di sistem beneran, biasanya sisa produk yang udah dihapus.
Sekarang JOIN-nya:
SELECT p.tanggal, pr.nama_produk, p.qty, pr.harga
FROM penjualan p
INNER JOIN produk pr ON p.id_produk = pr.id_produk
ORDER BY p.tanggal;
Hasilnya:
| tanggal | nama_produk | qty | harga |
|---|---|---|---|
| 2026-02-10 | Beras Premium 5kg | 3 | 68.500 |
| 2026-02-10 | Gula Pasir 1kg | 12 | 16.250 |
| 2026-02-11 | Minyak Goreng 2L | 7 | 34.750 |
| 2026-02-11 | Kopi Bubuk 200g | 9 | 21.375 |
| 2026-02-12 | Beras Premium 5kg | 2 | 68.500 |
Lima baris. Padahal tabel penjualan isinya enam. Transaksi 106 raib, soalnya id_produk = 9 nggak nemu pasangan.
Ini sifat INNER JOIN yang wajib kamu inget: dia diam-diam ngebuang baris. Nggak ada warning, nggak ada error. Kalau kamu nggak ngecek, omzet transaksi 106 hilang dari laporan.
Makanya biasain cek jumlah baris sebelum dan sesudah JOIN:
SELECT COUNT(*) FROM penjualan; -- 6
SELECT COUNT(*) FROM penjualan p
INNER JOIN produk pr ON p.id_produk = pr.id_produk; -- 5
Beda satu. Itu sinyal buat kamu nyelidikin, bukan langsung lanjut bikin chart.
Contoh kasus: omzet per produk Toko Berkah
JOIN sendirian jarang jadi tujuan akhir. Biasanya dia langkah pertama sebelum diagregasi. Ini query yang paling sering aku tulis buat rekap toko:
SELECT pr.nama_produk,
SUM(p.qty) AS total_qty,
SUM(p.qty * pr.harga) AS total_omzet
FROM penjualan p
INNER JOIN produk pr ON p.id_produk = pr.id_produk
GROUP BY pr.nama_produk
ORDER BY total_omzet DESC;
Hasilnya:
| nama_produk | total_qty | total_omzet |
|---|---|---|
| Beras Premium 5kg | 5 | 342.500 |
| Minyak Goreng 2L | 7 | 243.250 |
| Gula Pasir 1kg | 12 | 195.000 |
| Kopi Bubuk 200g | 9 | 192.375 |
Ada temuan menarik di sini. Gula kejual 12 unit, jauh lebih laris dari beras yang cuma 5 unit. Tapi omzet beras hampir dua kali lipat omzet gula.
Kalau pemilik toko cuma lihat kolom qty, dia bakal nambahin stok gula dan ngurangin beras. Padahal yang nyumbang duit paling besar justru beras. Ini alasan kenapa JOIN penting: angka qty doang nggak cukup buat ambil keputusan.
Teh Celup nggak muncul sama sekali di hasil, soalnya nggak pernah kejual. INNER JOIN ngebuang produk yang nggak punya transaksi. Kalau kamu justru mau lihat produk yang belum laku, pakai LEFT JOIN.
Apa beda ON dan WHERE di INNER JOIN?
ON nentuin gimana dua tabel disambungin. WHERE nyaring hasilnya setelah nyambung. Di INNER JOIN, dua-duanya ngasih hasil sama, tapi bacanya beda.
-- Syarat penyambung di ON, filter di WHERE (rekomendasi)
SELECT pr.nama_produk, SUM(p.qty * pr.harga) AS omzet
FROM penjualan p
INNER JOIN produk pr ON p.id_produk = pr.id_produk
WHERE pr.kategori = 'Sembako'
GROUP BY pr.nama_produk;
Hasilnya cuma tiga produk sembako, total omzet Rp 780.750.
Kenapa kebiasaan ini penting? Soalnya di LEFT JOIN, naruh filter di ON atau WHERE bikin hasil yang beda jauh. Kalau kamu udah biasain dari INNER JOIN, kamu nggak bakal kejebak nanti.
Kesalahan umum pakai INNER JOIN
- Nggak sadar baris hilang. INNER JOIN buang baris tanpa pasangan secara diam-diam. Selalu bandingin COUNT sebelum dan sesudah JOIN.
- Hasil dobel gara-gara kunci nggak unik. Kalau
id_produkmuncul dua kali di tabel produk, tiap transaksi yang cocok bakal digandain. Omzet kamu tiba-tiba dua kali lipat. Cek keunikan kunci pakaiSELECT id_produk, COUNT(*) FROM produk GROUP BY id_produk HAVING COUNT(*) > 1; - Lupa alias tabel. Kalau dua tabel punya kolom bernama sama, database bingung. Kasih alias pendek kayak
pdanpr, terus tulisp.qty, bukanqtypolos. - JOIN pakai kolom yang tipenya beda. Kolom
id_produkbertipe TEXT di satu tabel dan INTEGER di tabel lain? Hasilnya kosong tanpa error. Samain tipenya dulu. - Kolom kunci ada spasi tersembunyi. Ini penyebab JOIN gagal yang paling nyebelin, soalnya nggak keliatan mata. Bersihin pakai TRIM dulu.
FAQ
Apa itu INNER JOIN di SQL?
INNER JOIN adalah cara nggabungin dua tabel lewat kolom kunci yang nilainya sama. Hasilnya cuma baris yang ketemu pasangannya di kedua tabel. Baris yang nggak punya pasangan langsung dibuang. Contoh paling umum: nyambungin tabel penjualan ke tabel produk lewat id_produk, biar kamu bisa lihat nama produk, bukan cuma angka id-nya.
Apa bedanya INNER JOIN dan LEFT JOIN?
INNER JOIN cuma nyisain baris yang punya pasangan di dua tabel. LEFT JOIN nyimpen semua baris dari tabel kiri, walau nggak ada pasangannya di tabel kanan, dan kolom kanannya diisi NULL. Pakai INNER JOIN kalau kamu cuma butuh data yang lengkap. Pakai LEFT JOIN kalau kamu justru mau nemuin yang nggak punya pasangan, misalnya produk yang belum pernah laku.
Kenapa hasil INNER JOIN barisnya jadi lebih banyak?
Soalnya kolom kunci di salah satu tabel nggak unik. Kalau satu id_produk muncul dua kali di tabel produk, tiap baris penjualan yang cocok bakal digandain jadi dua. Cek dulu keunikan kuncinya pakai COUNT dan GROUP BY sebelum JOIN. Kalau totalnya membengkak, hampir pasti masalahnya di sini, bukan di query JOIN-nya.
Apa beda ON dan WHERE di INNER JOIN?
ON nentuin gimana dua tabel disambungin, WHERE nyaring hasil setelah disambungin. Di INNER JOIN, naruh syarat di ON atau WHERE hasilnya sama. Tapi di LEFT JOIN hasilnya beda jauh, jadi biasain dari sekarang: syarat penyambung taruh di ON, syarat filter taruh di WHERE.
Apakah INNER JOIN bisa lebih dari dua tabel?
Bisa. Tinggal tumpuk INNER JOIN berikutnya di bawahnya, misalnya penjualan JOIN produk lalu JOIN kategori. Tiap JOIN butuh klausa ON sendiri. Tapi hati-hati, tiap tabel tambahan yang kuncinya nggak unik bisa gandain baris. Cek jumlah barisnya tiap kali kamu nambah satu JOIN baru.
Penutup
INNER JOIN itu pintu masuk ke hampir semua analisis serius. Tabel transaksi nyimpen id, tabel master nyimpen artinya, dan JOIN yang nyatuin.
Dua kebiasaan yang bakal nyelametin kamu: cek COUNT sebelum dan sesudah JOIN, dan pastiin kolom kuncinya unik di tabel master.
Sintaks lengkap INNER JOIN per database ada di halaman fungsi INNER JOIN, dan istilah kunci penyambungnya aku jelasin di glossary foreign key. Referensi resminya bisa kamu cek di dokumentasi JOIN PostgreSQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel Terkait
7 SQL Client Gratis Terbaik buat Analis Data (2026)
Nggak perlu bayar buat nulis query. Ini 7 SQL client gratis yang beneran dipakai analis, plus kelebihan dan kekurangannya masing-masing.
SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim
Sepuluh aturan SQL style guide yang bikin query kamu kebaca sama tim — dan sama kamu sendiri 6 bulan lagi. Lengkap dengan contoh sebelum-sesudah.
Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya
Contoh soal take-home test SQL yang beneran dipakai perusahaan, dikerjain step by step — dari baca soal, nulis query, sampai nyusun insight yang bikin recruiter nengok.