Vì điều kiện lọc bảng bên phải bị đặt nhầm vào WHERE thay vì ON. LEFT JOIN sinh ra các dòng có cột bên phải toàn NULL; sau đó WHERE chạy và loại chính những dòng NULL đó → còn lại đúng bằng INNER JOIN.
sql
-- SAI: bien thanh inner join
SELECT c.id, o.total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'paid'; -- NULL <> 'paid' -> UNKNOWN -> bi loai
-- DUNG: dieu kien ve bang phai nam trong ON
SELECT c.id, o.total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.status = 'paid';Quy tắc ghi nhớ:
- Điều kiện về bảng bên phải của LEFT JOIN → đặt trong ON (lọc trước khi ghép, vẫn giữ dòng bên trái).
- Điều kiện về bảng bên trái → đặt ở WHERE (kết quả như nhau, nhưng rõ ý hơn).
- Muốn thật sự loại các khách không có đơn nào → dùng INNER JOIN cho tường minh, đừng dựa vào tác dụng phụ.
MySQL gọi quá trình optimizer nhận ra và hạ cấp này là outer join simplification; với INNER JOIN thì ON và WHERE tương đương nhau nên nhầm lẫn chỉ lộ ra ở outer join.