INNER JOIN

Memasangkan baris dua tabel dengan INNER JOIN dan membaca hasilnya.

Daftar isi

Topik ini membahas INNER JOIN, yaitu operator join (penggabungan) yang memasangkan baris dari dua tabel hanya jika kondisi yang ditentukan dalam ON terpenuhi. Pembahasan diawali dengan pengenalan dataset perpustakaan yang digunakan dalam modul ini, dilanjutkan dengan membaca hasil penggabungan baris demi baris, membuktikan kesetaraan penggunaan ON dan WHERE pada INNER JOIN, serta mengidentifikasi baris tanpa pasangan yang tidak muncul dalam hasil penggabungan. Setelah mempelajari topik ini, pembaca diharapkan mampu memperkirakan jumlah baris hasil INNER JOIN berdasarkan pasangan data yang tersedia tanpa harus menjalankan kueri terlebih dahulu.

Dataset perpustakaan#

Seluruh contoh pada modul ini menggunakan tiga tabel yang sama, yaitu buku, anggota, dan peminjaman, sehingga jumlah baris hasil join pada setiap topik saling menjelaskan. Tabel buku memuat enam judul, tabel anggota memuat enam anggota, dan tabel peminjaman memuat lima catatan pinjam bertanggal Maret 2026. Keadaan datanya sengaja dibuat mendidik, yaitu Farhan belum pernah meminjam satu buku pun, peminjaman keempat menunjuk id_buku 99 yang tidak ada di tabel buku, serta Peta Langit, Sejarah Kertas, dan Arsip Suara tidak sedang dipinjam. Dasar Algoritma dipinjam dua kali oleh anggota yang berbeda. Jalankan blok berikut untuk membangun dataset tersebut dan menampilkan seluruh isinya.

sql Pembuatan tiga tabel perpustakaan
CREATE TABLE buku (
  id INTEGER PRIMARY KEY,
  judul TEXT
);
CREATE TABLE anggota (
  id INTEGER PRIMARY KEY,
  nama TEXT
);
CREATE TABLE peminjaman (
  id INTEGER PRIMARY KEY,
  id_buku INTEGER,
  id_anggota INTEGER,
  tanggal_pinjam TEXT
);
INSERT INTO buku VALUES
  (1, 'Dasar Algoritma'),
  (2, 'Peta Langit'),
  (3, 'Kode dan Sandi'),
  (4, 'Sejarah Kertas'),
  (5, 'Jejak Angin'),
  (6, 'Arsip Suara');
INSERT INTO anggota VALUES
  (1, 'Ali'), (2, 'Budi'), (3, 'Citra'),
  (4, 'Dewi'), (5, 'Eka'), (6, 'Farhan');
INSERT INTO peminjaman VALUES
  (1, 1, 1, '2026-03-02'),
  (2, 3, 2, '2026-03-04'),
  (3, 1, 3, '2026-03-06'),
  (4, 99, 4, '2026-03-09'),
  (5, 5, 5, '2026-03-11');
SELECT * FROM peminjaman;
text Keluaran
1|1|1|2026-03-02
2|3|2|2026-03-04
3|1|3|2026-03-06
4|99|4|2026-03-09
5|5|5|2026-03-11

Keluaran menampilkan lima baris peminjaman dengan kolom id, id_buku, id_anggota, dan tanggal_pinjam. Baris keempat memiliki id_buku bernilai 99, yang tidak merujuk pada baris mana pun dalam tabel buku. Baris semacam ini disebut baris tanpa referensi valid (orphan row). Nama Farhan tidak muncul dalam tabel ini karena belum pernah melakukan peminjaman, sedangkan buku Sejarah Kertas tidak muncul karena belum pernah dipinjam. Kondisi ketika suatu data tidak memiliki pasangan inilah yang membedakan perilaku berbagai jenis JOIN pada topik-topik berikutnya.

Memasangkan baris dengan ON#

INNER JOIN bekerja dengan menilai kondisi ON untuk setiap kombinasi baris kedua tabel, kemudian meneruskan hanya kombinasi yang hasilnya benar. Kondisi yang paling lazim menghubungkan pengenal satu tabel dengan rujukannya di tabel lain, misalnya buku.id = peminjaman.id_buku. Relasi semacam ini dikenal sebagai kunci asing (foreign key), yaitu kolom yang menyimpan pengenal baris dari tabel lain. Jalankan query (perintah pembacaan data) berikut untuk memasangkan setiap peminjaman dengan judul bukunya.

sql INNER JOIN buku dan peminjaman
CREATE TABLE buku (id INTEGER PRIMARY KEY, judul TEXT);
CREATE TABLE anggota (id INTEGER PRIMARY KEY, nama TEXT);
CREATE TABLE peminjaman (id INTEGER PRIMARY KEY, id_buku INTEGER, id_anggota INTEGER, tanggal_pinjam TEXT);
INSERT INTO buku VALUES
  (1, 'Dasar Algoritma'), (2, 'Peta Langit'), (3, 'Kode dan Sandi'),
  (4, 'Sejarah Kertas'), (5, 'Jejak Angin'), (6, 'Arsip Suara');
INSERT INTO anggota VALUES
  (1, 'Ali'), (2, 'Budi'), (3, 'Citra'),
  (4, 'Dewi'), (5, 'Eka'), (6, 'Farhan');
INSERT INTO peminjaman VALUES
  (1, 1, 1, '2026-03-02'), (2, 3, 2, '2026-03-04'),
  (3, 1, 3, '2026-03-06'), (4, 99, 4, '2026-03-09'),
  (5, 5, 5, '2026-03-11');
SELECT judul, tanggal_pinjam
FROM buku
  INNER JOIN peminjaman ON buku.id = peminjaman.id_buku
ORDER BY peminjaman.id;
text Keluaran
Dasar Algoritma|2026-03-02
Kode dan Sandi|2026-03-04
Dasar Algoritma|2026-03-06
Jejak Angin|2026-03-11

Hasil kueri menampilkan empat baris, sedangkan tabel peminjaman memuat lima baris. Peminjaman yang merujuk id_buku 99 tidak muncul karena tidak ada baris pada tabel buku yang memenuhi kondisi ON. Akibatnya, baris tanpa pasangan tersebut tidak disertakan dalam hasil, tanpa memunculkan pesan kesalahan. Tiga peminjaman lainnya berhasil dipasangkan dengan buku masing-masing. Buku Dasar Algoritma muncul dua kali karena tercatat dalam dua transaksi peminjaman. Dengan demikian, hanya pasangan yang berhasil ditemukan yang disertakan dalam hasil INNER JOIN, sedangkan baris tanpa pasangan diabaikan.

Perhatikan bahwa kondisi ON dinilai untuk setiap kombinasi baris, bukan sekali per baris tabel kiri. Karena Dasar Algoritma dipinjam dua kali, satu baris buku itu dipasangkan dengan dua baris peminjaman yang berbeda. Perilaku ini menjadi dasar untuk memprediksi jumlah baris hasil pada bagian berikutnya.

Jumlah baris sama dengan jumlah pasangan#

Jumlah baris hasil INNER JOIN dapat dihitung dari pasangan yang cocok tanpa menjalankan query-nya. Satu baris yang dipasangkan dengan dua baris lain menghasilkan dua baris hasil, sedangkan baris tanpa pasangan tidak menyumbang apa pun. Jalankan query berikut yang menampilkan pengenal kedua tabel agar mekanisme pasangannya terlihat jelas.

sql Pasangan baris pada kedua sisi
CREATE TABLE buku (id INTEGER PRIMARY KEY, judul TEXT);
CREATE TABLE anggota (id INTEGER PRIMARY KEY, nama TEXT);
CREATE TABLE peminjaman (id INTEGER PRIMARY KEY, id_buku INTEGER, id_anggota INTEGER, tanggal_pinjam TEXT);
INSERT INTO buku VALUES
  (1, 'Dasar Algoritma'), (2, 'Peta Langit'), (3, 'Kode dan Sandi'),
  (4, 'Sejarah Kertas'), (5, 'Jejak Angin'), (6, 'Arsip Suara');
INSERT INTO anggota VALUES
  (1, 'Ali'), (2, 'Budi'), (3, 'Citra'),
  (4, 'Dewi'), (5, 'Eka'), (6, 'Farhan');
INSERT INTO peminjaman VALUES
  (1, 1, 1, '2026-03-02'), (2, 3, 2, '2026-03-04'),
  (3, 1, 3, '2026-03-06'), (4, 99, 4, '2026-03-09'),
  (5, 5, 5, '2026-03-11');
SELECT buku.id, judul, peminjaman.id, id_buku, id_anggota
FROM buku JOIN peminjaman ON buku.id = peminjaman.id_buku
ORDER BY peminjaman.id;
text Keluaran
1|Dasar Algoritma|1|1|1
3|Kode dan Sandi|2|3|2
1|Dasar Algoritma|3|1|3
5|Jejak Angin|5|5|5

Dua kolom pertama berasal dari buku dan tiga kolom sisanya berasal dari peminjaman. Baris buku dengan id 1 tampil dua kali karena dipasangkan dengan peminjaman id 1 dan id 3. Rumusnya sederhana, yaitu jumlah baris hasil sama dengan jumlah pasangan yang memenuhi kondisi ON. Dataset ini memuat empat pasangan buku dan peminjaman, sehingga hasilnya empat baris meskipun buku berisi enam baris dan peminjaman berisi lima baris.

ON dan WHERE yang setara#

Pada INNER JOIN, kondisi penggabungan boleh dipindahkan dari ON ke WHERE tanpa mengubah hasil. Dua query berikut membandingkan kedua bentuk itu pada kondisi yang sama persis.

sql Kondisi ON dan WHERE yang setara
CREATE TABLE buku (id INTEGER PRIMARY KEY, judul TEXT);
CREATE TABLE anggota (id INTEGER PRIMARY KEY, nama TEXT);
CREATE TABLE peminjaman (id INTEGER PRIMARY KEY, id_buku INTEGER, id_anggota INTEGER, tanggal_pinjam TEXT);
INSERT INTO buku VALUES
  (1, 'Dasar Algoritma'), (2, 'Peta Langit'), (3, 'Kode dan Sandi'),
  (4, 'Sejarah Kertas'), (5, 'Jejak Angin'), (6, 'Arsip Suara');
INSERT INTO anggota VALUES
  (1, 'Ali'), (2, 'Budi'), (3, 'Citra'),
  (4, 'Dewi'), (5, 'Eka'), (6, 'Farhan');
INSERT INTO peminjaman VALUES
  (1, 1, 1, '2026-03-02'), (2, 3, 2, '2026-03-04'),
  (3, 1, 3, '2026-03-06'), (4, 99, 4, '2026-03-09'),
  (5, 5, 5, '2026-03-11');
SELECT judul, tanggal_pinjam
FROM buku INNER JOIN peminjaman
  ON buku.id = peminjaman.id_buku
ORDER BY peminjaman.id;
SELECT judul, tanggal_pinjam
FROM buku INNER JOIN peminjaman
  WHERE buku.id = peminjaman.id_buku
ORDER BY peminjaman.id;
text Keluaran
Dasar Algoritma|2026-03-02
Kode dan Sandi|2026-03-04
Dasar Algoritma|2026-03-06
Jejak Angin|2026-03-11
Dasar Algoritma|2026-03-02
Kode dan Sandi|2026-03-04
Dasar Algoritma|2026-03-06
Jejak Angin|2026-03-11

Keluaran menampilkan dua kelompok yang masing-masing terdiri atas empat baris dengan hasil yang identik. Hal ini menunjukkan bahwa kedua bentuk penulisan tersebut memang setara pada INNER JOIN. Perhatikan bahwa pemindahan kondisi tidak memerlukan penyesuaian apa pun karena hanya terdapat satu kondisi. Pada kueri dengan banyak kondisi, pemisahan yang konsisten membantu memperjelas fungsi setiap kondisi. Letakkan kondisi penggabungan dua tabel pada ON dan kondisi penyaringan hasil pada WHERE. Keduanya memiliki makna yang berbeda pada LEFT JOIN. Dengan membiasakan pola ini sejak awal, risiko kesalahan pada pembahasan berikutnya dapat dikurangi.

Baris tanpa pasangan yang tidak muncul#

Baris tanpa pasangan tidak disertakan dalam hasil INNER JOIN dan tidak menghasilkan pesan kesalahan apa pun. Kehilangan data semacam ini sulit dikenali, terutama ketika jumlah datanya besar. Pada dataset ini, baris peminjaman dengan id_buku 99 tidak muncul karena buku yang dirujuk tidak tersedia dalam tabel buku. Jalankan kedua kueri berikut untuk melihat perbedaan jumlah barisnya.

sql Peminjaman tanpa pasangan buku
CREATE TABLE buku (id INTEGER PRIMARY KEY, judul TEXT);
CREATE TABLE anggota (id INTEGER PRIMARY KEY, nama TEXT);
CREATE TABLE peminjaman (id INTEGER PRIMARY KEY, id_buku INTEGER, id_anggota INTEGER, tanggal_pinjam TEXT);
INSERT INTO buku VALUES
  (1, 'Dasar Algoritma'), (2, 'Peta Langit'), (3, 'Kode dan Sandi'),
  (4, 'Sejarah Kertas'), (5, 'Jejak Angin'), (6, 'Arsip Suara');
INSERT INTO anggota VALUES
  (1, 'Ali'), (2, 'Budi'), (3, 'Citra'),
  (4, 'Dewi'), (5, 'Eka'), (6, 'Farhan');
INSERT INTO peminjaman VALUES
  (1, 1, 1, '2026-03-02'), (2, 3, 2, '2026-03-04'),
  (3, 1, 3, '2026-03-06'), (4, 99, 4, '2026-03-09'),
  (5, 5, 5, '2026-03-11');
SELECT COUNT(*) FROM peminjaman;
SELECT COUNT(*) FROM buku JOIN peminjaman ON buku.id = peminjaman.id_buku;
text Keluaran
5
4

Kueri pertama menghitung lima baris dalam tabel peminjaman, sedangkan kueri kedua hanya menghasilkan empat pasangan yang cocok. Selisih satu baris tersebut menunjukkan adanya baris tanpa pasangan yang tidak disertakan dalam hasil penggabungan. Jika seluruh data seharusnya memiliki referensi yang valid, perbedaan antara jumlah baris dalam tabel dan jumlah pasangan yang terbentuk dapat digunakan sebagai pemeriksaan berkala. Cara mengidentifikasi baris tanpa pasangan secara eksplisit menggunakan LEFT JOIN akan dibahas pada topik berikutnya.

Ringkasan#

  • INNER JOIN memasangkan baris dua tabel dan hanya meneruskan pasangan yang memenuhi kondisi ON.
  • Jumlah baris hasil sama dengan jumlah pasangan, sehingga satu baris yang dipasangkan dua kali menghasilkan dua baris.
  • Pada INNER JOIN, kondisi pada ON dan pada WHERE menghasilkan keluaran yang sama, sedangkan penempatan yang rapi memisahkan penggabungan dari penyaringan.
  • Baris yang tidak memiliki pasangan akan diabaikan dari hasil tanpa memunculkan pesan error.

Referensi#