Tại sao bạn luôn thấy nó khó hiểu?
Nếu bạn đang học SQL, có lẽ bạn đã từng gặp JOIN.
Lúc mới nhìn qua, bạn nghĩ JOIN khá đơn giản: chỉ cần lấy dữ liệu từ hai bảng rồi nối chúng lại với nhau. Nhưng càng học, bạn càng gặp nhiều khái niệm như INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN,… và bắt đầu thấy khá rối.
Thực tế, có thể hiểu JOIN rất đơn giản:
JOIN là cách kết hợp dữ liệu từ nhiều bảng dựa trên một mối quan hệ chung.
Ví dụ có hai bảng:
Users
| id | name |
|---|---|
| 1 | An |
| 2 | Bình |
| 3 | Cường |
Orders
| id | user_id | amount |
|---|---|---|
| 101 | 1 | 500 |
| 102 | 2 | 300 |
| 103 | 5 | 700 |
Ta có thể liên kết:
users.id = orders.user_id
Từ đó biết đơn hàng nào thuộc về user nào.
INNER JOIN
INNER JOIN chỉ lấy những dữ liệu có sự tương ứng ở cả hai bảng.
SELECT *
FROM users u
INNER JOIN orders o
ON u.id = o.user_id;
Kết quả chỉ có An và Bình, vì họ có order tương ứng.
| An | 500 |
| Bình | 300 |
Bạn có thể nhớ:
INNER JOIN → Chỉ lấy dữ liệu khớp ở hai bên.
LEFT JOIN
LEFT JOIN giữ toàn bộ dữ liệu của bảng bên trái, kể cả khi không tìm thấy dữ liệu tương ứng ở bảng bên phải.
SELECT *
FROM users u
LEFT JOIN orders o
ON u.id = o.user_id;
Kết quả sẽ có cả Cường:
| An | 500 |
| Bình | 300 |
| Cường | NULL |
Cường vẫn xuất hiện, nhưng thông tin về đơn hàng sẽ là NULL.
Điều này rất hữu ích khi bạn muốn lấy tất cả người dùng, kể cả những người chưa có đơn hàng (tìm những đối tượng chưa có dữ liệu liên quan ).
RIGHT JOIN
RIGHT JOIN hoạt động tương tự LEFT JOIN, nhưng ưu tiên giữ toàn bộ dữ liệu của bảng bên phải.
SELECT *
FROM users u
RIGHT JOIN orders o
ON u.id = o.user_id;
Order có user_id = 5 vẫn xuất hiện, mặc dù không tìm thấy user tương ứng:
| An | 500 |
| Bình | 300 |
| NULL | 700 |
Trong thực tế, LEFT JOIN thường được sử dụng nhiều hơn RIGHT JOIN vì có thể đổi vị trí hai bảng để đạt được kết quả tương đương.
Vậy OUTER JOIN là gì?
OUTER JOIN là cách gọi nhóm JOIN cho phép giữ lại những bản ghi không có dữ liệu tương ứng.
SELECT *
FROM users u
FULL OUTER JOIN orders o
ON u.id = o.user_id;
Kết quả:
| u.id | name | o.id | user_id |
|---|---|---|---|
| 1 | An | 101 | 1 |
| 1 | An | 102 | 1 |
| 2 | Bình | 103 | 2 |
| 3 | Cường | NULL | NULL |
Có thể hiểu đơn giản:
FULL OUTER JOIN
→ Giữ toàn bộ cả hai bảng
Do đó, khi nhìn thấy chữ OUTER, hãy nghĩ đến:
“Có giữ lại những dữ liệu không khớp hay không?”
Vậy JOIN khác nhau ở đâu?
Điểm quan trọng nhất không nằm ở việc nhớ tên.
Khi gặp một bài toán JOIN, tôi thường đặt câu hỏi:
“Tôi muốn giữ lại những dòng nào?”
| JOIN | Dữ liệu được giữ lại |
|---|---|
INNER JOIN | Chỉ những dòng khớp |
LEFT JOIN | Toàn bộ bảng bên trái |
RIGHT JOIN | Toàn bộ bảng bên phải |
FULL OUTER JOIN | Toàn bộ dữ liệu của cả hai bảng |
Chỉ cần bạn hiểu được bảng nào được giữ lại và bảng nào có thể xuất hiện NULL, việc phân biệt các loại JOIN sẽ trở nên đơn giản hơn rất nhiều.
Kết luận
JOIN không khó vì cú pháp. Nó khó chủ yếu vì bạn chưa hình dung được kết quả sau khi hai bảng được kết hợp.
Thay vì học thuộc:
INNER = ?LEFT = ?RIGHT = ?
Hãy tập trung vào một câu hỏi:
“Sau khi JOIN, tôi muốn giữ lại dữ liệu của bên nào?”
Khi trả lời được câu hỏi này, bạn sẽ dễ dàng chọn được loại JOIN phù hợp.


