LEFT JOIN & RIGHT JOIN: Menemukan yang Tak Punya Pasangan
Menampilkan semua baris dari satu sisi walau tanpa pasangan dengan LEFT JOIN, menemukan data "yatim" dengan IS NULL, dan kapan memakai RIGHT JOIN.
Masalah INNER JOIN: yang tak punya pasangan hilang
Pertanyaan bisnis: "Pelanggan mana yang belum pernah memesan sama sekali?" Dengan INNER JOIN mustahil dijawab, karena mereka justru tidak muncul. Kita butuh JOIN yang mempertahankan semua baris sisi kiri.
LEFT JOIN
SELECT pl.nama, p.id AS no_pesanan
FROM pelanggan pl
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id;
Aturannya: semua baris tabel kiri (yang ditulis setelah FROM) tetap tampil. Jika ada pasangan di tabel kanan, datanya ikut; jika tidak, kolom milik tabel kanan diisi NULL.
+-----------------+------------+
| nama | no_pesanan |
+-----------------+------------+
| Budi Santoso | 1 |
| Budi Santoso | 3 |
| Budi Santoso | 9 |
...
| Fitri Handayani | NULL | ← tidak punya pesanan
| Joko Susilo | NULL | ← tidak punya pesanan
+-----------------+------------+
Resep emas: mencari yang tidak punya pasangan
Karena yang tanpa pasangan berisi NULL di sisi kanan, saring dengan IS NULL pada kolom tabel kanan (gunakan kolom PK-nya):
SELECT pl.nama, pl.kota
FROM pelanggan pl
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id
WHERE p.id IS NULL;
Hasil: Fitri Handayani dan Joko Susilo, yaitu pelanggan yang belum pernah memesan. Resep ini dipakai di mana-mana: "produk yang belum pernah terjual", "siswa yang belum mengumpulkan tugas", "karyawan tanpa departemen".
LEFT JOIN + GROUP BY: menghitung termasuk nol
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;
Jebakan klasik: pakai COUNT(p.id), bukan COUNT(*). Fitri hanya punya satu baris (dengan NULL di sisi pesanan): COUNT(*) menghitungnya 1, padahal pesanannya 0. COUNT(p.id) mengabaikan NULL sehingga benar menghasilkan 0.
Satu lagi jebakan: WHERE vs ON
Menaruh syarat tabel kanan di WHERE (mis. WHERE p.status = 'lunas') membuang baris NULL dan mengubah LEFT JOIN menjadi INNER JOIN diam-diam. Kalau syarat itu hanya untuk memilih pasangan, taruh di ON:
LEFT JOIN pesanan p ON p.pelanggan_id = pl.id AND p.status = 'lunas'
RIGHT JOIN
RIGHT JOIN adalah cermin: semua baris tabel kanan dipertahankan. A LEFT JOIN B sama saja dengan B RIGHT JOIN A. Hampir semua orang memilih menulis LEFT JOIN saja (urutan baca kiri→kanan lebih natural), jadi kamu jarang menemui RIGHT JOIN di kode nyata.
| JOIN | Hasil |
|---|---|
INNER JOIN | Hanya pasangan yang cocok |
LEFT JOIN | Semua kiri + pasangan kanan (NULL bila tak ada) |
RIGHT JOIN | Semua kanan + pasangan kiri (NULL bila tak ada) |