LEFT & RIGHT JOIN — SQL

LEFT JOIN menampilkan SEMUA baris dari tabel kiri, meskipun tidak ada kecocokan di tabel kanan. SELECT u.name, COUNT(p.id) as jumlah_post FROM users u LEFT…

LEFT JOIN sama seperti INNER JOIN, ditambah semua baris tabel kiri yang gak punya pasangan. Kolom dari tabel kanan untuk baris itu diisi NULL. Mirip daftar pengumpulan tugas: guru menulis nama semua siswa dulu, lalu mencentang tugas yang masuk. Siswa yang belum mengumpulkan tetap ada di daftar, kolom tugasnya kosong.

🧪 Tebakan cepat: dengan data pelanggan dan pesanan yang sama seperti INNER JOIN, LEFT JOIN dari customers ke orders menghasilkan berapa baris, dan apa isi kolom produk untuk Andi? Tebak dulu, jawabannya ada di bagian "Langkah demi langkah".

Data yang dipakai

customers: 1 Budi, 2 Siti, 3 Andi.

orders

id customer_id product
1 1 Laptop
2 1 Mouse
3 2 Monitor
4 NULL Flashdisk

Dua baris gak punya pasangan: Andi (belum pernah pesan) dan Flashdisk (pembeli tamu, customer_id NULL). INNER JOIN membuang keduanya.

Langkah demi langkah

SELECT c.name AS nama, o.product AS produk
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
Pelanggan (kiri) Pasangan di orders Baris hasil
Budi Laptop, Mouse Budi, Laptop dan Budi, Mouse
Siti Monitor Siti, Monitor
Andi gak ada Andi, NULL
nama produk
Budi Laptop
Budi Mouse
Siti Monitor
Andi NULL

4 baris, dan produk Andi NULL. Itu jawaban tebakannya. NULL di sini artinya "gak ada pasangannya", bukan teks "NULL". Flashdisk tetap gak muncul, karena dia ada di tabel kanan.

RIGHT JOIN dan FULL OUTER JOIN

RIGHT JOIN kebalikannya: semua baris tabel kanan disimpan. Flashdisk muncul dengan nama NULL, Andi hilang. FULL OUTER JOIN (boleh ditulis FULL JOIN) menyimpan semua baris dari dua sisi.

JOIN Baris Yang ikut walau gak punya pasangan
INNER JOIN 3 gak ada
LEFT JOIN 4 Andi (produk NULL)
RIGHT JOIN 4 Flashdisk (nama NULL)
FULL OUTER JOIN 5 Andi dan Flashdisk

Jadi bedanya LEFT dan RIGHT cuma di tabel mana yang semua barisnya dipertahankan. customers c RIGHT JOIN orders o sama hasilnya dengan orders o LEFT JOIN customers c, makanya kebanyakan orang cukup memakai LEFT JOIN dan mengatur urutan tabelnya.

Soal dukungan: SQLite baru punya RIGHT dan FULL OUTER JOIN sejak versi 3.39 (2022). Lab, Playground dan latihan di sini memakai SQLite 3.49, jadi keempatnya jalan. PostgreSQL punya keempatnya, MySQL punya RIGHT JOIN tapi belum punya FULL OUTER JOIN.

Mencari yang gak punya pasangan

LEFT JOIN plus WHERE ... IS NULL menyisakan baris kiri yang gak punya pasangan:

SELECT c.name
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.id IS NULL;

Hasilnya cuma Andi: pelanggan yang belum pernah pesan. o.id dipakai karena id pesanan yang asli gak pernah kosong, jadi kalau dia NULL, pasti barisnya gak punya pasangan. Pakai IS NULL, bukan = NULL: perbandingan dengan NULL gak pernah bernilai benar, jadi WHERE o.id = NULL selalu memberi 0 baris.

📌 Menghitung dengan LEFT JOIN

SELECT c.name, COUNT(o.id) AS jumlah
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id;

Budi 2, Siti 1, Andi 0. Hati-hati dengan COUNT(*): dia menghitung baris, dan Andi punya satu baris (yang isinya NULL), jadi Andi dapat 1. COUNT(o.id) melewati NULL, jadi Andi dapat 0.

⚠️ Jebakan yang sering ketemu

TL;DR: LEFT JOIN = INNER JOIN + semua baris tabel kiri (di FROM) yang gak punya pasangan, dengan kolom tabel kanan berisi NULL. Dari 3 pelanggan dan 4 pesanan: INNER 3 baris, LEFT 4 (Andi, produk NULL), RIGHT 4 (Flashdisk, nama NULL), FULL OUTER 5. Bedanya LEFT dan RIGHT cuma sisi mana yang dipertahankan. LEFT JOIN ... WHERE o.id IS NULL mencari yang gak punya pasangan. Pakai IS NULL dan COUNT(o.id), dan jangan menyaring tabel kanan di WHERE kalau baris kiri harus tetap ada.

Yang akan kamu pelajari