Giả sử bạn có hai bảng: danh sách sinh viên và danh sách đăng ký khóa học của họ. Không phải sinh viên nào cũng đã đăng ký khóa học, và bạn muốn xem danh sách đầy đủ tất cả sinh viên, kể cả những bạn chưa chọn khóa nào. Nếu dùng INNER JOIN thì chỉ thấy những ai đã đăng ký, vậy còn những sinh viên còn lại thì sao? Đó là lúc LEFT JOIN phát huy tác dụng.
LEFT JOIN sẽ trả về tất cả các dòng từ bảng bên trái (bảng đầu tiên trong truy vấn) và các dòng tương ứng từ bảng bên phải. Nếu không có dòng tương ứng, các cột của bảng bên phải sẽ là NULL.
Cú pháp LEFT JOIN
SELECT
bang1.cot1,
bang1.cot2,
bang2.cot1,
bang2.cot2
FROM
bang1 LEFT JOIN bang2
ON
bang1.cot_chung = bang2.cot_chung;
bang1— là bảng "bên trái".bang2— là bảng "bên phải".cot_chung— cột chung để nối hai bảng.
Ví dụ dễ hiểu
Nếu bảng students như sau:
| student_id | name |
|---|---|
| 1 | Otto |
| 2 | Anna |
| 3 | Peter |
Còn bảng enrollments như sau:
| enrollment_id | student_id | course |
|---|---|---|
| 1 | 1 | Toán học |
| 2 | 1 | Vật lý |
| 3 | 2 | Sinh học |
Vậy truy vấn:
SELECT
students.name,
enrollments.course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
sẽ trả về:
| name | course |
|---|---|
| Otto | Toán học |
| Otto | Vật lý |
| Anna | Sinh học |
| Peter | NULL |
Nhìn nhé, kết quả vẫn có đầy đủ sinh viên, kể cả Peter, người chưa đăng ký khóa nào. Với Peter, cột course sẽ là NULL.
Ví dụ sử dụng LEFT JOIN
Ví dụ 1: Lấy danh sách tất cả sinh viên và các khóa học của họ
Giả sử bạn cần lấy danh sách đầy đủ sinh viên cùng với các khóa học mà họ đã đăng ký, nếu có. Nếu sinh viên chưa chọn khóa nào thì cũng phải hiển thị luôn.
Truy vấn vẫn như trên:
SELECT
students.name,
enrollments.course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
Kết quả:
| name | course |
|---|---|
| Otto | Toán học |
| Otto | Vật lý |
| Anna | Sinh học |
| Peter | NULL |
Đây là ví dụ kinh điển về cách dùng LEFT JOIN.
Ví dụ 2: Hiển thị sản phẩm và số lượng bán
Giả sử bạn có hai bảng:
Bảng products chứa tất cả sản phẩm:
| product_id | product_name |
|---|---|
| 1 | Điện thoại thông minh |
| 2 | Máy tính bảng |
| 3 | Laptop |
Bảng sales chứa dữ liệu bán hàng:
| sale_id | product_id | quantity |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 3 |
| 3 | 2 | 2 |
Bây giờ bạn muốn xem tất cả sản phẩm và số lượng bán, kể cả sản phẩm chưa bán được cái nào.
SELECT
products.product_name,
SUM(sales.quantity) AS total_sold
FROM
products LEFT JOIN sales
ON
products.product_id = sales.product_id
GROUP BY
products.product_name;
Kết quả:
| product_name | total_sold |
|---|---|
| Điện thoại thông minh | 8 |
| Máy tính bảng | 2 |
| Laptop | NULL |
Lưu ý và vấn đề khi dùng LEFT JOIN
Có cần NULL không?
Đôi khi LEFT JOIN sẽ trả về NULL ở những chỗ bạn không ngờ tới. Lúc này, bạn có thể thay NULL bằng giá trị dễ hiểu hơn với hàm COALESCE().
SELECT
students.name,
COALESCE(enrollments.course, 'Chưa chọn khóa') AS course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
Kết quả:
| name | course |
|---|---|
| Otto | Toán học |
| Otto | Vật lý |
| Anna | Sinh học |
| Peter | Chưa chọn khóa |
Dòng bị lặp không cần thiết
Nếu dữ liệu ở bảng bên phải có dòng trùng lặp, kết quả truy vấn sẽ có nhiều dòng hơn bạn nghĩ. Hãy chú ý dữ liệu bạn đang làm việc và dùng DISTINCT nếu không muốn bị lặp.
GO TO FULL VERSION