LEFT JOIN: Termasuk Data yang Tidak Punya Pasangan
LEFT JOIN, RIGHT JOIN, dan FULL JOIN; mencari data yang belum punya pasangan (anti-join); serta menghitung dengan LEFT JOIN agar nilai nol tetap muncul.
Analogi: LEFT JOIN itu seperti absensi kelas: semua murid (tabel kiri) tetap tercatat di daftar, walaupun ada yang tidak hadir. Murid yang tidak hadir muncul dengan kolom kehadiran kosong (NULL). INNER JOIN seperti daftar yang hanya memuat murid yang hadir.
Masalah INNER JOIN: data hilang
Dua pertanyaan bos yang tidak bisa dijawab dengan INNER JOIN:
- "Tampilkan semua buku, termasuk yang belum punya kategori."
- "Siapa saja pelanggan yang belum pernah memesan?"
Jawabannya: LEFT JOIN.
LEFT JOIN: semua dari tabel kiri
SELECT b.judul, k.nama AS kategori
FROM buku b
LEFT JOIN kategori k ON b.kategori_id = k.id;
Semua baris tabel kiri (buku) dipertahankan. Bila tidak ada pasangan di tabel kanan, kolom dari tabel kanan diisi NULL.
judul | kategori
----------------------------+-----------
Laskar Pelangi | Novel
...
Catatan Tanpa Kategori | (NULL)
Ringkasan semua jenis JOIN
| JOIN | Hasil |
|---|---|
INNER JOIN | Hanya baris yang cocok di kedua tabel |
LEFT JOIN | Semua tabel kiri + yang cocok dari kanan (sisanya NULL) |
RIGHT JOIN | Kebalikan LEFT (jarang dipakai; tukar urutan tabel lalu pakai LEFT) |
FULL JOIN | Semua baris dari kedua tabel |
CROSS JOIN | Semua kombinasi (hati-hati, bisa meledak jumlahnya) |
Pola emas: mencari yang "belum punya"
LEFT JOIN lalu saring IS NULL pada kolom tabel kanan:
SELECT pl.nama
FROM pelanggan pl
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id
WHERE p.id IS NULL; -- tidak ada pesanan yang cocok
Analogi: daftar hadir. LEFT JOIN dari daftar siswa ke daftar absen, lalu ambil yang kolom absennya kosong = siapa yang tidak hadir.
LEFT JOIN + COUNT: awas jebakan
Untuk menghitung jumlah pesanan per pelanggan termasuk yang nol, hitung kolom tabel kanan, bukan COUNT(*):
SELECT pl.nama, COUNT(p.id) AS jumlah_pesanan
FROM pelanggan pl
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id
GROUP BY pl.id, pl.nama
ORDER BY jumlah_pesanan DESC;
COUNT(*) akan menghitung 1 untuk pelanggan tanpa pesanan (baris NULL-nya tetap satu baris). COUNT(p.id) mengabaikan NULL sehingga hasilnya benar: 0.
Letak syarat penting: syarat yang menyaring tabel kanan sebaiknya diletakkan di ON (bukan WHERE), karena WHERE akan membuang baris NULL dan mengubah LEFT JOIN menjadi INNER JOIN diam-diam.
Kasus nyata: pelanggan yang belum pernah berbelanja
Tim marketing ingin mengirim voucher ke pelanggan yang sudah mendaftar tetapi belum pernah memesan. Triknya: LEFT JOIN lalu cari yang pasangannya NULL.
SELECT pl.nama, pl.email
FROM pelanggan pl
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id
WHERE p.id IS NULL;Pola "cari yang tidak punya pasangan" ini sangat umum: produk yang tidak pernah terjual, pengguna tidak aktif, dan sebagainya.
Kesalahan yang sering terjadi
- Menaruh syarat tabel kanan di
WHEREsehingga LEFT JOIN diam-diam berubah menjadi INNER JOIN. Taruh diON. - Salah arah: tabel yang ingin dipertahankan harus berada di kiri (sebelum kata JOIN).
- Menghitung dengan
COUNT(*)pada hasil LEFT JOIN. PakaiCOUNT(p.id)agar pelanggan tanpa pesanan bernilai 0.