Cơ bảnKiến thức cơ bản

JOIN trong SQL: Hướng dẫn INNER JOIN, LEFT JOIN, RIGHT JOIN

8 phút đọc0 lượt xem
#sql#join#database#mysql

JOIN trong SQL là gì?

Trong thực tế, cơ sở dữ liệu không chỉ có một bảng. Một hệ thống bán hàng có bảng customers (khách hàng), bảng orders (đơn hàng), bảng products (sản phẩm)... Để lấy thông tin có ý nghĩa, bạn cần kết hợp dữ liệu từ nhiều bảng lại — đó là lúc cần đến JOIN.

JOIN là câu lệnh SQL cho phép kết hợp các hàng từ hai hoặc nhiều bảng dựa trên một cột có liên quan giữa chúng — thường là khóa ngoại (foreign key) và khóa chính (primary key).

Trước hết, hãy tạo dữ liệu mẫu để dùng xuyên suốt bài viết:

-- Bảng khách hàng
CREATE TABLE customers (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);

-- Bảng đơn hàng
CREATE TABLE orders (
    id INT PRIMARY KEY,
    customer_id INT,
    product VARCHAR(100),
    amount DECIMAL(10,2)
);

-- Dữ liệu mẫu
INSERT INTO customers VALUES (1, 'Nguyễn Văn A', 'a@email.com');
INSERT INTO customers VALUES (2, 'Trần Thị B', 'b@email.com');
INSERT INTO customers VALUES (3, 'Lê Văn C', 'c@email.com');  -- Chưa có đơn hàng

INSERT INTO orders VALUES (1, 1, 'Laptop', 15000000);
INSERT INTO orders VALUES (2, 1, 'Chuột', 150000);
INSERT INTO orders VALUES (3, 2, 'Bàn phím', 500000);

Lưu ý: Lê Văn C (id=3) chưa có đơn hàng nào — điều này sẽ tạo sự khác biệt rõ ràng giữa các loại JOIN.

INNER JOIN — Lấy dữ liệu chung

INNER JOIN chỉ trả về các hàng có dữ liệu khớp ở cả hai bảng. Nếu một khách hàng không có đơn hàng, họ sẽ không xuất hiện trong kết quả.

SELECT customers.name, orders.product, orders.amount
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;

-- Kết quả:
-- name          | product   | amount
-- Nguyễn Văn A | Laptop    | 15000000
-- Nguyễn Văn A | Chuột     | 150000
-- Trần Thị B   | Bàn phím  | 500000
-- (Lê Văn C không xuất hiện vì không có đơn hàng)

INNER JOIN giống như phần giao nhau của hai tập hợp — chỉ lấy những gì tồn tại ở cả hai bên.

Khi nào dùng INNER JOIN: khi bạn chỉ muốn dữ liệu có liên kết đầy đủ ở cả hai bảng (ví dụ: chỉ lấy đơn hàng kèm tên khách hàng).

LEFT JOIN — Giữ toàn bộ bảng trái

LEFT JOIN trả về tất cả các hàng từ bảng bên trái, và dữ liệu khớp từ bảng bên phải. Nếu không có dữ liệu khớp bên phải, cột đó sẽ có giá trị NULL.

SELECT customers.name, orders.product, orders.amount
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id;

-- Kết quả:
-- name          | product   | amount
-- Nguyễn Văn A | Laptop    | 15000000
-- Nguyễn Văn A | Chuột     | 150000
-- Trần Thị B   | Bàn phím  | 500000
-- Lê Văn C     | NULL      | NULL   ← xuất hiện, nhưng không có đơn hàng

Khi nào dùng LEFT JOIN: khi bạn muốn lấy tất cả dữ liệu từ bảng chính, kể cả những bản ghi chưa có dữ liệu liên quan. Ví dụ: "danh sách tất cả khách hàng, kể cả người chưa mua hàng".

RIGHT JOIN — Giữ toàn bộ bảng phải

RIGHT JOIN là đối xứng của LEFT JOIN — trả về tất cả hàng từ bảng bên phải, và dữ liệu khớp từ bảng bên trái.

SELECT customers.name, orders.product, orders.amount
FROM customers
RIGHT JOIN orders ON customers.id = orders.customer_id;

-- Kết quả: tất cả đơn hàng + tên khách hàng (NULL nếu không tìm thấy)
-- Trong ví dụ này kết quả giống INNER JOIN vì mọi order đều có customer

Lưu ý thực tế: hầu hết developer dùng LEFT JOIN thay vì RIGHT JOIN (bằng cách đổi vị trí bảng), vì LEFT JOIN dễ đọc hơn khi bảng chính luôn ở bên trái.

So sánh các loại JOIN

Loại JOINTrả về gìKhi nào dùng
INNER JOINChỉ hàng khớp ở cả 2 bảngKhi cần dữ liệu liên kết đầy đủ
LEFT JOINTất cả bảng trái + khớp bảng phảiKhi bảng trái là "chính", bảng phải là "phụ"
RIGHT JOINTất cả bảng phải + khớp bảng tráiÍt dùng, thay bằng LEFT JOIN đổi vị trí
FULL OUTER JOINTất cả hàng cả 2 bảngMySQL: dùng UNION thay thế

Ví dụ thực tế — Database cửa hàng

Dùng alias (bí danh) để code ngắn gọn hơn, kết hợp WHERE và ORDER BY:

-- Dùng alias c và o để viết ngắn hơn
SELECT c.name AS ten_khach, o.product AS san_pham, o.amount AS gia_tien
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
WHERE o.amount > 200000
ORDER BY o.amount DESC;

-- Kết quả: chỉ đơn hàng > 200,000 VNĐ, sắp xếp từ cao xuống thấp
-- ten_khach     | san_pham  | gia_tien
-- Nguyễn Văn A | Laptop    | 15000000
-- Trần Thị B   | Bàn phím  | 500000
-- Đếm số đơn hàng mỗi khách hàng
SELECT c.name, COUNT(o.id) AS so_don_hang, SUM(o.amount) AS tong_tien
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name
ORDER BY tong_tien DESC;

-- Kết quả:
-- name          | so_don_hang | tong_tien
-- Nguyễn Văn A | 2           | 15150000
-- Trần Thị B   | 1           | 500000
-- Lê Văn C     | 0           | NULL

Tổng kết

JOIN là một trong những kỹ năng SQL quan trọng nhất. Những điểm cần nhớ:

  • INNER JOIN: chỉ lấy dữ liệu khớp ở cả 2 bảng
  • LEFT JOIN: lấy tất cả bảng trái, dùng nhiều nhất trong thực tế
  • Luôn dùng alias (c, o) để code dễ đọc hơn
  • Có thể kết hợp JOIN với WHERE, ORDER BY, GROUP BY

Xem thêm: SQL là gì? | MySQL là gì? | Các câu lệnh SQL cơ bản

Về tác giả

Ảnh đại diện tác giả Kenji — họa tiết hình học

Kenji

Kỹ sư phần mềm full-stack (Web), hơn 5 năm kinh nghiệm thực tế

  • Python
  • DB
  • Hạ tầng
  • Đào tạo & cố vấn
  • AI

Làm việc cùng đồng nghiệp người Việt, tôi thấy thiếu tài liệu kỹ thuật rõ ràng bằng tiếng Việt. codeahoc là nơi tôi chia sẻ theo hướng thực tế, dễ áp dụng.

Nguyên tắc nội dung

  • Ưu tiên nguồn gốc và góc nhìn từ thực tế triển khai.
  • Nếu có sai sót, nội dung sẽ được cập nhật và sửa kịp thời.

Khóa học liên quan

The Complete SQL Bootcamp: Go from Zero to Hero

SQL từ cơ bản đến nâng cao với PostgreSQL.

4.7399.000 ₫
Xem khóa học →

MongoDB - The Complete Developer's Guide

Học MongoDB toàn diện: CRUD, aggregation, indexing.

4.6499.000 ₫
Xem khóa học →