JOIN là ghép dòng giữa hai bảng theo điều kiện. Hình dung bằng hai vòng tròn Venn:
- INNER JOIN: chỉ phần giao — dòng có match ở cả hai bảng (vd chỉ users CÓ order).
- LEFT JOIN: toàn bộ bảng trái + phần giao; bên phải không match thì là
NULL(vd TẤT CẢ users, kể cả chưa mua). - RIGHT JOIN: ngược lại LEFT, hiếm dùng — nên viết lại thành LEFT cho dễ đọc.
- FULL OUTER JOIN: cả hai vòng,
NULLở bên thiếu. - CROSS JOIN: tích Descartes M×N dòng — nguy hiểm với bảng lớn.
Mẹo dùng LEFT JOIN tìm dòng "mồ côi": ... LEFT JOIN orders o ON ... WHERE o.id IS NULL cho ra users chưa từng mua.
Bẫy phỏng vấn kinh điển: lọc cột bảng phải trong WHERE sẽ biến LEFT JOIN thành INNER JOIN (vì dòng NULL bị loại). Muốn giữ, đặt điều kiện vào ON:
SELECT * FROM a LEFT JOIN b ON a.id = b.a_id AND b.col = 'x';Lưu ý hiệu năng: JOIN trên foreign key có index thì rất nhanh; JOIN trên cột không index sẽ quét toàn bảng.
A JOIN merges rows from two tables by a condition. Picture two Venn circles:
- INNER JOIN: only the intersection — rows matching in both tables (e.g. only users WITH orders).
- LEFT JOIN: the entire left table + intersection; the right side is
NULLwhen there's no match (e.g. ALL users, including those who never bought). - RIGHT JOIN: the opposite of LEFT, rarely used — rewrite as LEFT for readability.
- FULL OUTER JOIN: both circles,
NULLon the missing side. - CROSS JOIN: Cartesian product M×N rows — dangerous with large tables.
Trick: use LEFT JOIN to find "orphan" rows — ... LEFT JOIN orders o ON ... WHERE o.id IS NULL returns users who never purchased.
Classic interview trap: filtering a right-table column in WHERE turns a LEFT JOIN into an INNER JOIN (NULL rows get dropped). To keep them, put the condition in ON:
SELECT * FROM a LEFT JOIN b ON a.id = b.a_id AND b.col = 'x';Performance note: JOINs on indexed foreign keys are fast; JOINs on non-indexed columns scan the whole table.