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
customerskeordersmenghasilkan 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;
FROM customers c: tabel kiri. LEFT JOIN menyimpan semua barisnya.LEFT JOIN orders o: tabel kanan. Barisnya cuma ikut kalau punya pasangan.ON c.id = o.customer_id: syarat pasangannya, sama persis dengan INNER JOIN.
| 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
- Masih menulis
INNER JOINatauJOINsaja. Hasilnya 3 baris dan Andi hilang. Latihan meminta 4 baris dengan Andi di kolomnama. - Urutan tabel terbalik.
FROM orders LEFT JOIN customersmenyimpan semua pesanan, bukan semua pelanggan. Tabel yang semua barisnya mau dipertahankan ditulis diFROM. - Menyaring tabel kanan di
WHERE.WHERE o.product = 'Laptop'setelah LEFT JOIN membuang Andi juga, karenaNULL = 'Laptop'gak benar. Kalau baris kiri harus tetap ada, taruh syaratnya diON:ON c.id = o.customer_id AND o.product = 'Laptop'. = NULLdanCOUNT(*). PakaiIS NULL, dan hitung kolom tabel kanan denganCOUNT(o.id).
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.