SQL là một ngôn ngữ mạnh mẽ để thao tác dữ liệu, đặc biệt khi kết hợp dữ liệu từ các bảng khác nhau. Hôm nay các bạn hãy theo chân DATAPOT khám phá xem hai cách phổ biến để hợp nhất các bảng trong SQL là gì nhé. Nhưng với ai đã bỏ lỡ qua các bài viết giá trị trong phần trước, hãy cùng xem lại tại đây nhé.
Mục lục
Kết hợp bảng sử dụng JOIN
Join là mệnh đề trong SQL, được dùng để kết nối dữ liệu từ hai hay nhiều bảng lại với nhau. JOIN cho phép truy vấn các cột dữ liệu từ nhiều bảng khác nhau để trả về trong cùng một tập kết quả.
JOIN thường được sử dụng để kết hợp dữ liệu trong cơ sở dữ liệu có quan hệ (Relational Database).
Khóa chính và khóa ngoại
Khóa chính (Primary Key – PK)
Khóa chính được sử dụng để định danh từng dòng dữ liệu trong bảng.
Đặc điểm:
- Khoá chính chứa giá trị không trùng lặp.
- Mỗi bảng chỉ có một khóa chính duy nhất (Khoá chính có thể là một trường hoặc tổ hợp các trường).
- Khóa chính không được chứa NULL.
Khoá ngoại (Foreign Key – FK)
Khóa ngoại chứa giá trị tham chiếu dùng để liên kết với khóa chính của bảng khác.
Đặc điểm:
- Khoá ngoại có thể là một trường hoặc tổ hợp trường.
- Một bảng dữ liệu có thể có nhiều khóa ngoại trong 1 bảng.
- Khóa ngoại có thể chứa (NULL).
Ví dụ:
Nhìn vào lược đồ (Schema) SaleLT:

- Bảng Customer có PK là CustomerID.
- SalesOrderDetail có PK là SalesOrderDetailID.
- SalesOrderHeader có PK là SalesOrderID.
- SalesOrderDetail có FK là ProductID và SalesOrderID.
- SalesOrderHeader có FK là AddressID và CustomerID.
Các loại JOIN
Kết hợp điểm chung (Inner join)
INNER JOIN trả về kết quả là các bản ghi mà trường được join ở hai bảng khớp nhau, các bản ghi chỉ xuất hiện ở một trong hai bảng sẽ bị loại.

Cú pháp của INNER JOIN:
SELECT
A.Col_Name,
B.Col_Name
FROM Table_A
INNER JOIN Table_B
On A.Key = B.Key
Ta có:
Bảng Customer gồm 847 hàng.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.Customer.
- SELECT *: Truy vấn tất cả các hàng trong bảng dữ liệu.
Bảng CustomerAddress gồm 417 hàng.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.CustomerAddress.
- SELECT *: Truy vấn tất cả các hàng trong bảng dữ liệu.
Ví dụ: INNER JOIN bảng Customer và CustomerAddress để truy vấn dữ liệu từ cột AddressType.

Giải thích câu lệnh truy vấn:
- INNER JOIN: Kết hợp điểm chung bảng Customer được gán tên CST với bảng CustomerAddress được gán tên CTA.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính CustomerID trong bảng Customer và khoá ngoại CustomerID trong bảng CustomerAddress.
Kết hợp trái (Left join)
Nếu bảng A LEFT JOIN với bảng B thì kết quả gồm các bản ghi có trong bảng A, với các bản ghi không có mặt trong bảng B thì các cột từ B được điền NULL. Các bản ghi chỉ có trong B mà không có trong A sẽ không được trả về.
Bảng được xác định là left trong phép JOIN là bảng được viết trước.

Cú pháp của LEFT JOIN:
SELECT
A.Col_Name,
B.Col_Name
FROM Table_A
LEFT JOIN Table_B
ON A.Key = B.Key
Ví dụ: Chọn bảng dữ liệu adventureworks, kết hợp trái giữa bảng Customer và Customer Address

Giải thích câu lệnh truy vấn:
- LEFT JOIN: Kết hợp trái bảng Customer được gán tên CST với bảng CustomerAddress được gán tên CTA.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính CustomerID trong bảng Customer và khoá ngoại CustomerID trong bảng CustomerAddress.
Kết hợp phải (Right join)
Nếu bảng được kết hợp phải với bảng B thì kết quả gồm các bản ghi có trong bảng B. Với các bản ghi không có mặt trong bảng A thì các cột từ bảng A được trả về NULL. Các bản ghi chỉ có trong bảng A mà không có trong bảng B sẽ không được trả về.

Cú pháp của RIGHT JOIN:
SELECT
A.Col_Name,
B.Col_Name
FROM Table_A
RIGHT JOIN Table_B
On A.Key = B.Key
Ví dụ: Chọn bảng dữ liệu adventureworks, kết hợp phải giữa bảng Customer và Customer Address.

Giải thích câu lệnh truy vấn:
- RIGHT JOIN: Kết hợp phải bảng Customer được gán tên CST với bảng CustomerAddress được gán tên CTA.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính CustomerID trong bảng Customer và khoá ngoại CustomeID trong bảng bảng CustomerAddress.
Kết hợp chéo (Cross join)
Kết hợp chéo (Cross join) là kết hợp giữa các hàng của hai bảng với nhau, mỗi hàng trong bảng thứ nhất sẽ kết hợp với N hàng của bảng thứ hai. Kết quả của kết hợp chéo (Cross join) sẽ có số hàng bằng tích số của hai bảng.
Do kết quả trả ra của Cross join có thể rất lớn là tích số của hai bảng, cần cân nhắc sự cần thiết khi sử dụng kết hợp chéo (Cross join).

Cú pháp của CROSS JOIN:
SELECT
FROM Table_A
CROSS JOIN Table_B
Ví dụ: Kết hợp bảng Customer (gồm 847 hàng) và CustomerAddress (gồm 417 hàng) bằng kết hợp chéo (Cross join).
Kết quả trả về là tích của 2 bảng là 353.199 hàng.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.Customer được gán dưới tên CST.
- CROSS JOIN: Kết hợp chéo bảng Customer được gán tên CST với bảng CustomerAddress được gán tên CTA.
Một hành trình vững chắc luôn cần người đồng hành đúng. Khóa học SQL trong lộ trình Data Analytics Foundation Plus không chỉ trao kiến thức, mà còn có mentor tận tâm giúp bạn đi xa hơn!
Kết hợp tất cả (Outer join/Full Outer Join)
Kết hợp chung (Outer join/Full Outer Join/FULL Join) là kết hợp tất cả các hàng với nhau.
Nếu không có sự trùng khớp giữa hai bảng với nhau, giá trị không xác định (NULL) sẽ được trả về cho các cột của bảng chứa các giá trị thiếu.

Cú pháp của FULL JOIN:
SELECT
A.Col_Name,
B.Col_Name
FROM Table_A
FULL JOIN Table_B
On A.Key = B.Key
Ví dụ: Kết hợp chung giữa bảng Customer và bảng (Table) CustomerAddress. Truy vấn các cột CustomerID, FirstNam, LastName, AddressID, AddressType.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.Customer được gán dưới tên CST.
- FULL JOIN: Kết hợp tất cả bản ghi của bảng Customer được gán tên CST với bảng CustomerAddress được gán tên CTA.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính CustomerID trong bảng Customer và khoá ngoại CustomerID trong bảng bảng CustomerAddress.
Kết hợp với nhiều hơn 2 bảng
JOIN nhiều hơn 2 bảng được phát triển từ phép JOIN thông thường. Thay vì chỉ JOIN 2 bảng thì chúng ta JOIN nhiều hơn 2 bảng.
Cú pháp của JOIN nhiều hơn 2 bảng:
ON t1.Key2 = t3.Key2
SELECT
Col_1,
Col_2,...
FROM Table 1 AS t1
LEFT/RIGHT/FULL/INNER JOIN Table 2 AS t2
ON t1.Key1 = t2.Key1
LEFT/RIGHT/FULL/INNER JOIN Table 3 AS t3
ON t1.Key2 = t3.Key2
Ví dụ: Từ 3 bảng trong bộ dữ liệu FactInternetSales, DimProduct, DimCustomer thuộc bộ dữ liệu AdventureWorksDW2019, truy vấn các cột ProductKey, FirstName, Color, SalesAmount. Với điều kiện, các đơn hàng có bán sản phẩm có Color = ‘Red’ và Customer FirstName bắt đầu bằng chữ A.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng dbo.FactInternetSales được gán dưới tên FIS.
- WHERE: Lọc bản ghi thoả mãn các đơn hàng có bán sản phẩm có Color = ‘Red’ và Customer FirstName bắt đầu bằng chữ A.
- LEFT JOIN: Kết hợp trái bảng DimProduct được gán tên DP với bảng FactInternetSales được gán tên FIS.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính ProductKey trong bảng DimProduct và khoá ngoại ProductKey trong bảng FactInternetSales.
- LEFT JOIN: Sau khi kết hợp bảng FactInternetSales và DimProduct, tiếp tục kết hợp trái bảng DimCustomer được gán tên DC.
- ON: Khai báo điều kiện kết hợp bảng từ cột khoá chính CustomerKey trong bảng DimCustomer và khoá ngoại CustomerKey trong bảng FactInternetSales.
- SELECT: Truy vấn các cột FIS.ProductKey, DC.FirstName, DP.Color, FIS.SalesAmount.
Kết hợp với chính nó (Self Join)
Self Join về bản chất vẫn là phép Join thông thường, tuy nhiên thay vì kết hợp với một bảng khác thì sẽ sử dụng mối quan hệ về dữ liệu có sẵn ở trong bảng để Join với chính nó.
Self Join thường được sử dụng với dữ liệu có mối quan hệ phân cấp và phân tầng. Ví dụ như dữ liệu mô hình tổ chức (Khối – Phòng ban), dữ liệu nhân sự (Cấp quản lý – Cấp trực thuộc),…
Cú pháp của Self Join:
SELECT
A.Col_Name,
B.Col_Name,...
FROM Table 1 AS A
LEFT/RIGHT/INNER/FULL JOIN Table 1 AS B
ON A.Key = B.Key
Ví dụ: Ta có bảng dữ liệu dbo.DimEmployee thuộc bộ dữ liệu AdventureWorksDW2020. Thực hiện truy vấn tên người quản lý tương ứng với từng nhân viên (Sử dụng Self Join).

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng DimEmployee được gán tên DE.
- LEFT JOIN: Kết hợp trái bảng DimEmployee với bảng PE.
- ON: Khai báo điều kiện kết hợp từ cột ParentEmployeeKey trong bảng DimEmployee và cột EmployeeKey bảng PE.
Các lưu ý khi viết JOIN
Lưu ý 1: Về Alias tên bảng
Khi thực hiện JOIN, ngầm định sẽ phải cần Alias tên bảng đem kết hợp. Khi Alias, hãy sử dụng các tên viết tắt và mang tính gợi nhớ đến bảng gốc.

Lưu ý 2: Lỗi Ambigous column name

Đây là một lỗi thường xuyên gặp khi mới thực hành viết phép JOIN. Nguyên nhân lỗi này từ việc gọi tên cột CustomerID nhưng tên cột này xuất hiện ở cả 2 bảng Customer và CustomerAddress. Vậy nên cần khai báo rõ ràng cột CustomerID đến từ bảng nào bằng cách khai báo tên bảng Alias đằng trước tên cột (Ví dụ: CST.CustomerID).

Sau khi viết lại thành CST.CustomerID thì không còn lỗi như trước. Ngoài ra, đối với cột FirstName tuy không có tên Alias của bảng đằng trước nhưng không bị lỗi Ambigous là vì cột FirstName chỉ tồn tại duy nhất ở bảng Customer (CST).
Mặc dù vậy, vẫn khuyến khích sử dụng tên Alias bảng kèm đằng trước các cột để câu lệnh rõ ràng và mạch lạc hơn.
Kết hợp bảng sử dụng UNION
UNION và UNION ALL
UNION
UNION kết hợp các cột từ hai hay nhiều mệnh đề SELECT theo chiều dọc và không bao gồm các dòng trùng lặp.
Đặc điểm:
- Khi UNION các câu lệnh SELECT cần trả về số cột dữ liệu bằng nhau.
- Các cột tương ứng cần có cùng kiểu dữ liệu.
- UNION sẽ gộp cả NULL.
Cú pháp của UNION:
SELECT
Col_1,
Col_2,...
FROM Table_1
UNION
SELECT
Col_1,
Col_2,...
FROM Table_2
Ví dụ: Kết hợp các đơn hàng từ Purchasing sources (Gồm 4.012 hàng) và Sales sources (Gồm 31.465 hàng) và loại bỏ giá trị trùng lặp.
Tổng số hàng trả về 29.224.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng PurchaseOrderHeader, SalesOrderHeader.
- UNION: Gộp các cột không bao gồm các dòng trùng lặp giữa 2 bảng với nhau.
UNION ALL
Tương tự như UNION, UNION ALL kết hợp cột từ hai hay nhiều mệnh đề SELECT theo chiều dọc. Tuy nhiên, không loại bỏ các dòng trùng lặp nếu có.
Đặc điểm:
- Khi UNION ALL các câu lệnh SELECT cần trả về số cột dữ liệu bằng nhau.
- Các cột tương ứng cần có cùng kiểu dữ liệu.
- UNION ALL sẽ gộp cả NULL.
Cú pháp của UNION ALL:
SELECT
Col_1,
Col_2,...
FROM Table_1
UNION ALL
SELECT
Col_1,
Col_2,...
FROM Table_2
Ví dụ: Kết hợp các đơn hàng từ Purchasing sources và Sales sources, sử dụng gộp tất cả (UNION ALL).
Tổng số hàng trả về 35.477.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng PurchaseOrderHeader, SalesOrderHeader.
- UNION ALL: Gộp các cột giữ nguyên các dòng trùng lặp giữa 2 bảng với nhau.
Các bạn có thể đọc thêm để phân biệt rõ ràng hơn giữa JOIN và UNION.

Một số lý thuyết tập hợp (Set theory) khác
Bên cạnh UNION và UNION ALL được giới thiệu chính, bạn có thể tham khảo thêm các lý thuyết tập hợp khác là INTERSECT và EXCEPT.
Intersect
INTERSECT truy vấn các bản ghi đồng thời xuất hiện trong 2 câu truy vấn đã chọn.
Đặc điểm
- INTERSECT có trả lại giá trị không tồn tại (NULL).
- INTERSECT không trả lại các giá trị trùng lặp.
- Tổng số cột được chọn của 2 bảng phải bằng nhau.

Lưu ý: Tên cột và kiểu dữ liệu phải giống nhau trong 2 câu lệnh SELECT.
Cú pháp của INTERSECT:
SELECT
Col_1,
Col_2,...
FROM Table_A
INTERSECT
SELECT
Col_1,
Col_2,...
FROM Table_B
Ví dụ: Bạn cần truy vấn những SalesOrderID đồng thời xuất hiện trong 2 bảng là bảng (Table) SalesOrderDetail và bảng (Table) SalesOrderID.
Ta dùng INTERSECT để truy vấn dữ liệu đề bài yêu cầu:

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.SalesOrderDetail, SalesLT.SalesOrderHeader.
- INTERSECT: Truy vấn các bản ghi đồng thời xuất hiện tại 2 bảng SalesLT.SalesOrderDetail và SalesLT.SalesOrderHeader.
Exception
Exception dùng để truy vấn ra các giá trị trong kết quả câu truy vấn bảng 1 và loại trừ kết quả trùng khớp với câu truy vấn bảng 2.

Cú pháp của EXCEPT:
SELECT
Col_1,
Col_2,...
FROM Table_A
EXCEPT
SELECT
Col_1,
Col_2,...
FROM Table_B
Để hiểu rõ hơn ta cùng xem ví dụ sau:
Từ bảng (Table) Product gồm 295 hàng và bảng ProductAndDescription gồm 1.764 hàng bạn phải truy vấn ProductID chung của 2 bảng, ngoại trừ ProductID xuất hiện trong bảng vProductAnDescription.
Ta dùng từ khóa (Key Word) EXCEPT để thực hiện:
Do giá trị “907” là giá trị duy nhất có trong bảng ProductID nên sau khi thực hiện truy vấn ta có kết quả nhận được là 1 hàng với giá trị “907”.

Giải thích câu lệnh truy vấn:
- FROM: Dữ liệu được lấy từ bảng SalesLT.Product, SalesLT.vProductAndDescription.
- EXCEPT: Truy vấn những bản ghi có trong bảng SalesLT.Product và loại trừ các bản ghi có xuất hiện trong bản ghi SalesLT.vProductAndDescription.
Chúng ta đã học cách hợp nhất các bảng trong SQL bằng hai phương thức khác nhau: JOIN và UNION. Tổng kết lại, JOIN cho phép chúng ta kết hợp dữ liệu dựa trên một cột hoặc điều kiện chung, trong khi UNION cho phép chúng ta kết hợp dữ liệu bằng cách nối thêm các hàng từ bảng này sang bảng khác. DATAPOT hy vọng rằng bài đăng này đã giúp bạn hiểu những kiến thức cơ bản về việc hợp nhất các bảng trong SQL, giúp bạn chọn được phương pháp tốt nhất cho nhu cầu của mình. Nếu bạn có bất kỳ câu hỏi hoặc phản hồi nào, xin vui lòng để lại bình luận bên dưới. Cảm ơn các bạn độc giả thân yêu!
Một hành trình vững chắc luôn cần người đồng hành đúng. Khóa học SQL trong lộ trình Data Analytics Foundation Plus không chỉ trao kiến thức, mà còn có mentor tận tâm giúp bạn đi xa hơn!
Kết nối thêm với chúng mình
Fanpage
Cộng đồng Data, AI và Tự động hóa 200,000+ thành viên
- Data Analytics and Business Intelligence Vietnam
- Data Science Explorer Community: Cộng đồng khám phá Khoa học dữ liệu – FTU
- Cùng bớt việc với Power BI, Power Automate, Power Apps
- Luyện thi chứng chỉ Microsoft (PL300, DP900, DP080, PL900,…)
- DATAPOT ALUMNI
Youtube
Zalo
- [DATAPOT] Power BI Hub
- [DATAPOT] Power Platform Hub
- Data, AI & Tự động hoá cho Doanh nghiệp bứt phá
- Cộng đồng Data, AI và tự động hóa
- Datapot Internship 2025
- [DATAPOT] Phân tích dữ liệu Performance Ads
Chúc bạn luôn thành công trong công việc và cuộc sống!
Data Analyst

