VLOOKUP và JOIN
Bạn sẽ học được
- Vì sao VLOOKUP và JOIN giải cùng một bài toán ghép dữ liệu.
- Cách chuyển một công thức VLOOKUP quen thuộc sang JOIN.
- Khi nào dùng LEFT JOIN thay vì JOIN.
- Những giới hạn của VLOOKUP mà SQL không có.
- Cách kiểm tra kết quả ghép không bị nhân dòng.
Khái niệm cốt lõi
VLOOKUP tìm một giá trị theo khóa ở bảng tra cứu rồi trả về một cột bên phải. JOIN ghép hai bảng theo điều kiện khóa và trả về tất cả cột cần dùng. Cùng mục đích, khác cách tiếp cận:
| VLOOKUP (Excel) | JOIN (SQL) |
|---|---|
=VLOOKUP(A2, Khach!A:D, 3, 0) | JOIN customers c ON c.id = o.customer_id |
| Chỉ lấy một cột mỗi công thức | Lấy mọi cột của cả hai bảng |
| Khóa tra cứu phải nằm bên trái | Không ràng buộc thứ tự cột |
| Chỉ lấy kết quả khớp đầu tiên | Lấy mọi kết quả khớp |
| Bảng tra cứu cùng file | Bảng có thể ở database khác |
Ví dụ chuyển đổi
Trong Excel, để thêm tên khách vào bảng đơn hàng:
=IFERROR(VLOOKUP(B2, Khach!$A:$D, 2, 0), "Không tìm thấy")Trong SQL, tương đương:
SELECT o.id,
o.order_date,
o.status,
c.name AS ten_khach,
c.city
FROM orders o
JOIN customers c ON c.id = o.customer_id
ORDER BY o.order_date;Điểm khác quan trọng: VLOOKUP trả một cột; JOIN trả cả name và city trong cùng một truy vấn. Không cần viết thêm công thức cho từng cột.
LEFT JOIN và dòng không khớp
IFERROR(..., "Không tìm thấy") trong Excel tương ứng LEFT JOIN trong SQL: giữ mọi dòng bên trái, kể cả khi không có bản ghi khớp.
SELECT o.id,
o.order_date,
c.name AS ten_khach
FROM orders o
LEFT JOIN customers c ON c.id = o.customer_id
WHERE c.id IS NULL;Truy vấn này trả về các đơn không có khách hàng tương ứng — dữ liệu mồ côi. Đây là kiểm tra chất lượng dữ liệu rất hữu ích mà VLOOKUP khó làm gọn: bạn phải lọc toàn bộ cột kết quả tìm #N/A.
Ngược lại, JOIN (inner join) loại các dòng không khớp. Chọn loại nào là quyết định nghiệp vụ:
- Muốn báo cáo doanh thu theo khách: dùng
JOINnếu mọi đơn phải có khách hợp lệ. - Muốn kiểm tra dữ liệu thiếu: dùng
LEFT JOIN ... WHERE c.id IS NULL. - Muốn giữ mọi đơn dù thiếu thông tin khách: dùng
LEFT JOIN.
Giới hạn của VLOOKUP mà JOIN không có
- Chỉ tra bên phải. Khóa phải ở cột đầu; muốn tra ngược phải dùng
INDEX/MATCHhoặcXLOOKUP. - Chỉ trả một kết quả. Nếu khóa xuất hiện nhiều lần, VLOOKUP lấy dòng đầu tiên — âm thầm bỏ các dòng còn lại. JOIN trả đủ, và bạn thấy ngay số dòng tăng.
- So khớp kiểu dữ liệu.
"001"và1có thể không khớp nhau trong Excel. Trong SQL, kiểu cột được định nghĩa rõ nhưng vẫn có thể lỗi nếu so chuỗi với số. - Không ghép nhiều điều kiện. JOIN cho phép
ON a.id = b.id AND a.ngay = b.ngay. - Không tổng hợp. VLOOKUP lấy giá trị; muốn tổng theo khóa phải dùng
SUMIFhoặc PivotTable. SQL dùngGROUP BY.
Kiểm tra ghép không nhân dòng
Nếu bảng tra cứu có khóa trùng, JOIN sẽ nhân dòng và làm sai mọi tổng. Kiểm tra trước:
-- Khóa trong bảng tra cứu phải duy nhất
SELECT id, COUNT(*) AS so_lan
FROM customers
GROUP BY id
HAVING COUNT(*) > 1;Kết quả rỗng nghĩa là khóa duy nhất. Nếu có dòng, phải quyết định giữ bản ghi nào trước khi JOIN — đây chính là lý do VLOOKUP "che" lỗi còn JOIN thì phơi ra.
Sau khi JOIN, so số dòng:
SELECT COUNT(*) AS sau_join,
COUNT(DISTINCT o.id) AS so_don
FROM orders o
JOIN customers c ON c.id = o.customer_id;Hai số phải bằng nhau nếu mỗi đơn có đúng một khách. Chênh lệch nghĩa là bảng khách có khóa trùng.
Ghép nhiều bảng
Excel thường cần nhiều cột VLOOKUP chồng nhau. SQL nối tiếp:
SELECT o.id,
o.order_date,
c.name AS ten_khach,
p.name AS ten_san_pham,
oi.quantity,
oi.unit_price,
oi.quantity * oi.unit_price AS thanh_tien
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN order_items oi ON oi.order_id = o.id
JOIN products p ON p.id = oi.product_id
WHERE o.status = 'completed';Lưu ý hạt dữ liệu: kết quả ở hạt dòng sản phẩm trong đơn, nên SUM(thanh_tien) đúng nhưng COUNT(*) không phải số đơn. Dùng COUNT(DISTINCT o.id) khi cần đếm đơn.
Thực hành
- Viết công thức VLOOKUP lấy tên khách từ
customer_id, rồi viết JOIN tương đương. - Chạy
LEFT JOIN ... WHERE c.id IS NULLđể tìm đơn mồ côi. - Kiểm tra
customers.idcó trùng không. - Ghép ba bảng
orders,order_items,productsvà tính thành tiền từng dòng. - So
COUNT(*)vớiCOUNT(DISTINCT o.id)trong truy vấn trên.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
| Doanh thu tăng bất thường | JOIN bảng có khóa trùng | Kiểm tra khóa duy nhất trước |
| Mất đơn không có khách | Dùng JOIN thay LEFT JOIN | Dùng LEFT JOIN khi cần giữ |
| Kết quả thiếu cột | Nghĩ JOIN như VLOOKUP một cột | Chọn thêm cột trong SELECT |
| Lỗi so sánh khóa | Khác kiểu dữ liệu | Ép kiểu hoặc chuẩn hoá khóa |
| Muốn lấy dòng mới nhất | JOIN lấy mọi dòng khớp | Dùng DISTINCT ON hoặc window |
#N/A ở Excel | Không có bản ghi khớp | Trong SQL là dòng NULL sau LEFT JOIN |
Tóm tắt
- VLOOKUP và JOIN cùng mục đích; JOIN linh hoạt và minh bạch hơn.
LEFT JOINtương ứngIFERROR, giữ dòng không khớp.- VLOOKUP che khóa trùng; JOIN phơi ra qua số dòng tăng.
- Kiểm tra khóa duy nhất và so
COUNT(*)vớiCOUNT(DISTINCT ...). - JOIN nhiều bảng thay cho nhiều cột VLOOKUP, nhưng phải nhớ hạt dữ liệu.
Use ← → to move between lessons