Chuyển đến nội dung chính
Mô-đun 3 · Bài học 2 trong tổng số 410/57 trong khóa học~10 min
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

SQL
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.

SQL
-- 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:

SQL
-- 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ó

tập thể dục#sql.m3.l2.e1
Nỗ lực: 0Đang tải…

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.

Đang tải trình chỉnh sửa…
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

tập thể dục#sql.m3.l2.e2
Nỗ lực: 0Đang tải…

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.

Đang tải trình chỉnh sửa…
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ử