🧚 Dengar! Beekeeper Studio adalah GUI database yang cepat, modern, dan open source Unduh
2 Juli 2025 Oleh Matthew Rathbone

SQL JOIN menggabungkan baris dari dua tabel dengan mencocokkan kolom yang sama-sama dimiliki keduanya, misalnya author_id milik buku dan id milik penulis. Jenis join menentukan apa yang terjadi pada baris yang tidak cocok. Contoh-contohnya berjalan di PostgreSQL, MySQL, SQLite, dan SQL Server.

Cara menggunakan SQL JOIN

Letakkan tabel kedua setelah JOIN, lalu tentukan bagaimana barisnya cocok dengan baris tabel pertama di ON:

SELECT columns
FROM table_a
JOIN table_b ON table_a.key = table_b.key;

Setiap contoh di bagian ini menggabungkan dua tabel yang sama: Butler menulis dua buku, Asimov tidak menulis satu pun, dan tidak ada yang tahu siapa penulis Beowulf.

INNER JOIN

Diagram Inner Join

INNER JOIN hanya mengembalikan baris yang cocok di kedua tabel. JOIN saja berarti INNER JOIN.

-- Input: authors
-- id | name
-- ---+--------
-- 1  | Le Guin
-- 2  | Butler
-- 3  | Asimov

-- Input: books
-- title                | author_id
-- ---------------------+----------
-- The Dispossessed     | 1
-- Kindred              | 2
-- Parable of the Sower | 2
-- Beowulf              | NULL

SELECT a.name, b.title
FROM authors a
INNER JOIN books b ON a.id = b.author_id;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Kindred
-- Butler  | Parable of the Sower

Asimov tidak punya buku dan Beowulf tidak punya penulis, jadi keduanya tidak muncul.

LEFT JOIN

Diagram Left Join

LEFT JOIN (atau LEFT OUTER JOIN) mengembalikan setiap baris dari tabel kiri, yaitu tabel setelah FROM. Jika tabel kanan tidak punya pasangan, kolomnya bernilai NULL.

-- Input: the authors and books tables above

SELECT a.name, b.title
FROM authors a
LEFT JOIN books b ON a.id = b.author_id;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Kindred
-- Butler  | Parable of the Sower
-- Asimov  | NULL

RIGHT JOIN

Diagram Right Join

RIGHT JOIN (atau RIGHT OUTER JOIN) adalah kebalikannya: setiap baris dari tabel kanan, dengan NULL jika tabel kiri tidak punya pasangan.

-- Input: the authors and books tables above

SELECT a.name, b.title
FROM authors a
RIGHT JOIN books b ON a.id = b.author_id;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Kindred
-- Butler  | Parable of the Sower
-- NULL    | Beowulf

FULL OUTER JOIN

Diagram Full Outer Join

FULL OUTER JOIN mengembalikan setiap baris dari kedua tabel, dipasangkan jika memungkinkan dan diisi NULL jika tidak. MySQL tidak memilikinya: lihat “Sintaks alternatif” di bawah.

-- Input: the authors and books tables above

SELECT a.name, b.title
FROM authors a
FULL OUTER JOIN books b ON a.id = b.author_id;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Kindred
-- Butler  | Parable of the Sower
-- NULL    | Beowulf
-- Asimov  | NULL

CROSS JOIN

Diagram Cross Join

CROSS JOIN memasangkan setiap baris satu tabel dengan setiap baris tabel lainnya, jadi tidak ada ON. Dua ukuran dan dua warna menghasilkan empat kombinasi; 1.000 baris kali 1.000 baris menghasilkan satu juta, jadi gunakan pada tabel kecil.

-- Input: sizes
-- size
-- ----
-- S
-- M

-- Input: colors
-- color
-- -----
-- Red
-- Blue

SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c;

-- Output:
-- size | color
-- -----+------
-- S    | Red
-- S    | Blue
-- M    | Red
-- M    | Blue

LEFT ANTI JOIN

Diagram Left Anti Join

Left anti join mengembalikan baris dari tabel kiri yang tidak punya pasangan di tabel kanan. Tidak ada keyword khusus untuk ini: lakukan LEFT JOIN dan ambil baris yang sisi kanannya bernilai NULL.

-- Input: the authors and books tables above

SELECT a.name
FROM authors a
LEFT JOIN books b ON a.id = b.author_id
WHERE b.author_id IS NULL;

-- Output:
-- name
-- ------
-- Asimov

RIGHT ANTI JOIN

Diagram Right Anti Join

Right anti join mengembalikan baris dari tabel kanan yang tidak punya pasangan di tabel kiri.

-- Input: the authors and books tables above

SELECT b.title
FROM authors a
RIGHT JOIN books b ON a.id = b.author_id
WHERE a.id IS NULL;

-- Output:
-- title
-- -------
-- Beowulf

Aturan yang perlu diketahui

  • NULL tidak pernah cocok dengan apa pun, bahkan dengan NULL lainnya. author_id Beowulf yang NULL tidak cocok dengan penulis mana pun, jadi hanya join yang mempertahankan buku tanpa pasangan yang mengembalikannya.
  • Sebuah baris muncul sekali untuk setiap baris yang cocok dengannya. Butler muncul dua kali di atas karena ia cocok dengan dua buku. Jika Anda lalu menjumlahkan kolom dari tabel authors, nilainya terhitung dua kali.
  • Pada outer join, kondisi untuk tabel lainnya harus ditaruh di ON. Jika di WHERE, kondisi itu berjalan setelah join dan membuang baris NULL yang baru saja dipertahankan join:
-- Input: the authors and books tables above

-- Only Butler is left: the WHERE drops every author whose title is NULL
SELECT a.name, b.title
FROM authors a
LEFT JOIN books b ON a.id = b.author_id
WHERE b.title LIKE 'K%';

-- Output:
-- name   | title
-- -------+--------
-- Butler | Kindred

-- Every author is kept, with a book only where it starts with K
SELECT a.name, b.title
FROM authors a
LEFT JOIN books b ON a.id = b.author_id AND b.title LIKE 'K%';

-- Output:
-- name    | title
-- --------+--------
-- Le Guin | NULL
-- Butler  | Kindred
-- Asimov  | NULL

Sintaks alternatif

MySQL tidak punya FULL OUTER JOIN. Sebagai gantinya, gabungkan LEFT JOIN dengan baris tanpa pasangan dari RIGHT JOIN:

-- MySQL
-- Input: the authors and books tables above

SELECT a.name, b.title
FROM authors a LEFT JOIN books b ON a.id = b.author_id
UNION ALL
SELECT a.name, b.title
FROM authors a RIGHT JOIN books b ON a.id = b.author_id
WHERE a.id IS NULL;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Parable of the Sower
-- Butler  | Kindred
-- Asimov  | NULL
-- NULL    | Beowulf

SQLite sebelum versi 3.39 tidak punya RIGHT JOIN atau FULL OUTER JOIN: tukar urutan tabel dan gunakan LEFT JOIN.

Anti join juga bisa ditulis dengan NOT EXISTS. Hindari NOT IN untuk ini: jika subquery mengembalikan satu NULL saja, seperti author_id Beowulf di sini, NOT IN tidak mengembalikan apa pun:

-- Input: the authors and books tables above

SELECT a.name
FROM authors a
WHERE NOT EXISTS (SELECT 1 FROM books b WHERE b.author_id = a.id);

-- Output:
-- name
-- ------
-- Asimov

SELECT a.name
FROM authors a
WHERE a.id NOT IN (SELECT author_id FROM books);

-- Output:
-- name
-- ----
-- (0 rows)

Jika kolom yang dicocokkan punya nama yang sama di kedua tabel, Anda bisa menulis JOIN books USING (author_id) sebagai pengganti kondisi ON, kecuali di SQL Server.

Kode lama sering menuliskan tabel dengan koma dan menaruh pencocokan di WHERE. Itu adalah INNER JOIN yang ditulis dengan cara lain. Hilangkan WHERE-nya, maka hasilnya menjadi CROSS JOIN:

-- Input: the authors and books tables above

SELECT a.name, b.title
FROM authors a, books b
WHERE a.id = b.author_id;

-- Output:
-- name    | title
-- --------+---------------------
-- Le Guin | The Dispossessed
-- Butler  | Kindred
-- Butler  | Parable of the Sower

Kapan sebaiknya menggunakan SQL JOIN?

Gunakan join setiap kali data yang Anda butuhkan tersebar di beberapa tabel. Join mana yang dipakai bergantung pada apa yang harus terjadi pada baris yang tidak cocok, dan sebagian besar kasus termasuk salah satu dari lima berikut.

Baris karyawan menyimpan ID departemen, tetapi laporan membutuhkan nama departemennya. INNER JOIN mengambilnya, dan membuang baris yang tidak punya data untuk dicari.

Mempertahankan baris tanpa pasangan

Jika data terkait bersifat opsional, misalnya karyawan yang belum ditempatkan di departemen, INNER JOIN akan diam-diam menyembunyikannya. LEFT JOIN mempertahankan setiap baris dari tabel utama dan mengisi kekosongan dengan NULL.

Menampilkan setiap item, termasuk yang kosong

Laporan sering membutuhkan setiap departemen, kategori, atau pelanggan, termasuk yang belum berisi apa pun. Jadikan tabel itu sebagai tabel yang semua barisnya dipertahankan: di urutan pertama dengan LEFT JOIN, atau di urutan kedua dengan RIGHT JOIN.

Menemukan baris tanpa pasangan

Pelanggan yang tidak pernah memesan, produk yang tidak pernah terjual, karyawan tanpa departemen: anti join menemukan yang hilang, sehingga juga berguna untuk mengecek kualitas data.

Membuat setiap kombinasi

CROSS JOIN menghasilkan baris yang belum ada: setiap ukuran dalam setiap warna, setiap karyawan untuk setiap pelatihan, atau setiap toko pada setiap hari dalam laporan.

Contoh nyata SQL JOIN

Mahasiswa dan mata kuliahnya

Relasi many-to-many membutuhkan dua INNER JOIN melalui tabel penghubung yang mengaitkan mahasiswa dengan mata kuliah. Mei tidak terdaftar di mata kuliah mana pun, jadi ia tidak ditampilkan:

-- Input: students
-- id | name
-- ---+------
-- 1  | Amara
-- 2  | Lucas
-- 3  | Mei

-- Input: enrollments
-- student_id | course_id | grade
-- -----------+-----------+------
-- 1          | 10        | A
-- 1          | 20        | B
-- 2          | 10        | B

-- Input: courses
-- id | course_name
-- ---+------------
-- 10 | Databases
-- 20 | Statistics

SELECT s.name, c.course_name, e.grade
FROM students s
INNER JOIN enrollments e ON s.id = e.student_id
INNER JOIN courses c ON e.course_id = c.id;

-- Output:
-- name  | course_name | grade
-- ------+-------------+------
-- Amara | Databases   | A
-- Amara | Statistics  | B
-- Lucas | Databases   | B

Pengguna dengan profil opsional

Tidak semua pengguna sudah mengisi profil. LEFT JOIN mempertahankan semuanya:

-- Input: users
-- id | username
-- ---+---------
-- 1  | rosa_m
-- 2  | devon
-- 3  | kai_l

-- Input: user_profiles
-- user_id | bio
-- --------+------------------------
-- 1       | Data engineer in Lisbon
-- 3       | Loves SQL puzzles

SELECT u.username, p.bio
FROM users u
LEFT JOIN user_profiles p ON u.id = p.user_id;

-- Output:
-- username | bio
-- ---------+------------------------
-- rosa_m   | Data engineer in Lisbon
-- devon    | NULL
-- kai_l    | Loves SQL puzzles

Jumlah pesanan untuk setiap pelanggan

Untuk menyertakan pelanggan tanpa pesanan, lakukan LEFT JOIN dari customers. Lalu hitung kolom dari tabel orders: COUNT(*) ikut menghitung baris buatan LEFT JOIN untuk Omar, sehingga ia akan mendapat 1, bukan 0:

-- Input: customers
-- id | name
-- ---+------------
-- 1  | Harper Lee
-- 2  | Omar Haddad
-- 3  | Yuki Tanaka

-- Input: orders
-- id  | customer_id | total
-- ----+-------------+-------
-- 101 | 1           | 59.90
-- 102 | 3           | 120.00
-- 103 | 1           | 14.50

-- Wrong: COUNT(*) counts Omar's NULL row
SELECT c.name, COUNT(*) AS order_count
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name
ORDER BY c.id;

-- Output:
-- name        | order_count
-- ------------+------------
-- Harper Lee  | 2
-- Omar Haddad | 1
-- Yuki Tanaka | 1

-- Right: COUNT(o.id) skips it
SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name
ORDER BY c.id;

-- Output:
-- name        | order_count
-- ------------+------------
-- Harper Lee  | 2
-- Omar Haddad | 0
-- Yuki Tanaka | 1

Invoice dan pembayaran yang tidak cocok

FULL OUTER JOIN yang hanya mempertahankan baris tanpa pasangan bisa mencocokkan dua daftar sekaligus dalam satu query: invoice 502 belum dibayar, dan pembayaran 9003 ditujukan untuk invoice yang tidak ada:

-- Input: invoices
-- invoice_id | amount
-- -----------+-------
-- 501        | 120.00
-- 502        | 75.50
-- 503        | 300.00

-- Input: payments
-- payment_id | invoice_id | paid
-- -----------+------------+-------
-- 9001       | 501        | 120.00
-- 9002       | 503        | 300.00
-- 9003       | 504        | 42.00

-- MySQL has no FULL OUTER JOIN: use the UNION ALL form under "Alternative syntax"
SELECT i.invoice_id, i.amount, p.payment_id, p.invoice_id AS paid_invoice
FROM invoices i
FULL OUTER JOIN payments p ON p.invoice_id = i.invoice_id
WHERE i.invoice_id IS NULL OR p.payment_id IS NULL;

-- Output:
-- invoice_id | amount | payment_id | paid_invoice
-- -----------+--------+------------+-------------
-- 502        | 75.50  | NULL       | NULL
-- NULL       | NULL   | 9003       | 504

Pendapatan harian setiap toko, termasuk hari tanpa penjualan

Lakukan CROSS JOIN antara toko dan hari untuk mendapatkan satu baris per toko per hari, lalu LEFT JOIN data penjualan ke grid tersebut. York tidak menjual apa pun pada 6 Oktober, tetapi tetap mendapat baris:

-- Input: stores
-- store
-- -----
-- Leeds
-- York

-- Input: days
-- day
-- ----------
-- 2026-10-05
-- 2026-10-06

-- Input: sales
-- store | day        | amount
-- ------+------------+-------
-- Leeds | 2026-10-05 | 410.00
-- Leeds | 2026-10-06 | 385.50
-- York  | 2026-10-05 | 220.00

SELECT st.store, d.day, COALESCE(SUM(s.amount), 0.00) AS takings
FROM stores st
CROSS JOIN days d
LEFT JOIN sales s ON s.store = st.store AND s.day = d.day
GROUP BY st.store, d.day
ORDER BY st.store, d.day;

-- Output:
-- store | day        | takings
-- ------+------------+--------
-- Leeds | 2026-10-05 | 410.00
-- Leeds | 2026-10-06 | 385.50
-- York  | 2026-10-05 | 220.00
-- York  | 2026-10-06 | 0.00

Bacaan lanjutan tentang SQL JOIN

Di blog ini:

Dokumentasi resmi:

Beekeeper Studio Adalah GUI Database Gratis & Open Source

Tool query & editor SQL terbaik yang pernah saya pakai. Semua yang saya butuhkan untuk mengelola database ada di sini. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio cepat, intuitif, dan mudah digunakan. Beekeeper mendukung banyak sekali database, dan berjalan mulus di Windows, Mac, dan Linux.

Versi Linux Beekeeper punya fitur 100% lengkap, tanpa potong kompas, tanpa kompromi fitur.

Apa Kata Pengguna tentang Beekeeper Studio

★★★★★
"Beekeeper Studio sepenuhnya menggantikan workflow SQL lama saya. Cepat, intuitif, dan membuat kerja dengan database kembali menyenangkan."
— Alex K., Database Developer
★★★★★
"Saya sudah mencoba banyak GUI database, tetapi Beekeeper punya keseimbangan sempurna antara fitur dan kesederhanaan. Langsung jalan."
— Sarah M., Full Stack Engineer

Siap Meningkatkan Workflow SQL Anda?

download Unduh Gratis