Bài học theo mô-đun (2/4)
Giữ mọi thứ ở bên trái: LEFT JOIN
INNER JOIN từ bài học trước có tác dụng phụ quan trọng: nó
xóa các hàng không khớp. Nếu nhân viên không có bộ phận
(department_id là NULL), chúng biến mất khỏi kết quả.
Đôi khi đó là những gì bạn muốn. Tuy nhiên, thường thì không phải vậy: trong một báo cáo nhân sự
điều cần thiết là phải gặp tất cả nhân viên, kể cả những người không có phòng ban,
và biết họ là ai. Đó là mục đích của LEFT JOIN (đầy đủ, LEFT OUTER JOIN).
Nó hoạt động như thế nào
SELECT columns
FROM table_a
LEFT JOIN table_b ON table_a.x = table_b.y;Đọc bằng tiếng Anh: "giữ tất cả hàng table_a; cho mỗi hàng cố gắng
đính kèm một hàng từ table_b; nếu không có sự trùng khớp, hãy điền vào các cột từ
table_b với NULL".
Từ khóa là LEFT: có nghĩa là "bảng bên trái", tức là từ được viết
sau FROM. Tất cả các hàng của nó luôn tồn tại.
-- All employees, including those without a department:
SELECT e.first_name,
e.last_name,
d.name AS dipartimento
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id;Trong tập dữ liệu của chúng tôi, truy vấn này trả về 10 hàng (mỗi hàng một nhân viên). Andrea
Costa, người có department_id = NULL, xuất hiện cùng dipartimento = NULL
thay vì biến mất.
Tìm các hàng "không khớp"
Một kết quả rất hữu ích: bằng cách lọc IS NULL trên một cột của
bảng bên phải bạn tìm thấy chính xác các hàng không khớp:
-- Orphan employees: no department assigned
SELECT e.first_name, e.last_name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
WHERE d.id IS NULL;Thủ thuật này được sử dụng mọi lúc trong thế giới thực: "tìm cho tôi đơn hàng không có khách hàng", "sản phẩm chưa có đánh giá", "người dùng chưa bao giờ đăng nhập trong".
Hãy thử nó
Trả về tên (first_name) và họ (last_name) của những nhân viên KHÔNG được chỉ định bộ phận. Một hoặc nhiều hàng, hai cột.
Hiển thị gợi ý
Hoàn thành WHERE với d.id IS NULL — bạn muốn các hàng mà LEFT JOIN không tìm thấy bộ phận phù hợp.
Giải pháp khả dụng sau 3 lần thử
Xem lại bài tập
Liệt kê tất cả các phòng ban (departments.name) và bên cạnh chúng là số lượng nhân viên, bao gồm cả các phòng ban không có nhân viên (hiển thị 0 cho những phòng ban đó). Gợi ý: bắt đầu từ các phòng ban và thực hiện THAM GIA TRÁI với nhân viên, sau đó NHÓM THEO + ĐẾM.
Hiển thị gợi ý
Sử dụng COUNT(e.id) (không phải COUNT(*)) để đếm 0 khi không có kết quả khớp: COUNT(*) sẽ tính 1 vì hàng LEFT JOIN có NULL.
Giải pháp khả dụng sau 3 lần thử