Nếu bạn cần viết hai câu truy vấn SELECT khác nhau nhưng bạn muốn nó trả về một danh sách kết quả duy nhất thì bạn phải sử dụng toán tử UNION. Toán tử này cũng ít khi sử dụng khi bạn viết ứng dụng Web nhưng cũng nên tìm hiểu vì biết đâu sau này cần.
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.
1. Toán tử UNION trong MySQL
Toán tử UNION
cho phép bạn nối kết quả của hai hoặc nhiều câu truy vấn lại với nhau để trở thành một danh sách kết quả duy nhất. Cú pháp của MySQL UNION
như sau:
SELECT column1, column2 UNION [DISTINCT | ALL] SELECT column1, column2 UNION [DISTINCT | ALL] …
Bài viết này được đăng tại [free tuts .net]
Tuy nhiên khi sử dụng UNION trong MySQL chúng ta cần phải tuân thủ những nguyên tắc sau đây:
- Số lượng colums trong tất cả các lệnh
SELECT
phải bằng nhau - Mỗi column tương ứng vị trí phải có cùng kiểu dữ liệu và độ dài
Theo mặc định thì UNION
sẽ loại bỏ các kết quả trùng lặp của các câu SELECT
nên nó tạo cho chúng ta hai lựa chọn sau:
- Nếu chọn
UNION DISTINCT
thì nó sẽ loại bỏ kết quả trùng. - Nếu chọn
UNION ALL
thì nó giữ lại kết quả trùng. - Nếu bạn không chọn gì thì mặc định nó sẽ lấy
UNION DISTINCT
2. Một số ví dụ UNION trong MySQL
Trước tiên bạn tạo database, hai tables và thêm một số dữ liệu bằng cách chạy lệnh SQL sau:
CREATE DATABASE uni_db; USE uni_db; CREATE TABLE news_1 [ id INT[11] NOT NULL AUTO_INCREMENT PRIMARY KEY, title VARCHAR[255] ] ENGINE = INNODB; CREATE TABLE news_2 [ id INT[11] NOT NULL AUTO_INCREMENT PRIMARY KEY, title VARCHAR[255] ] ENGINE = INNODB; INSERT INTO news_1[title] VALUES['Tin Thoi Su']; INSERT INTO news_1[title] VALUES['Tin The Thao']; INSERT INTO news_1[title] VALUES['Tin Quoc Te']; INSERT INTO news_1[title] VALUES['Tin Do day']; INSERT INTO news_1[title] VALUES['Tin Khung Bo']; INSERT INTO news_2[title] VALUES['Ngay Quoc Te']; INSERT INTO news_2[title] VALUES['Ngay Phu Nu']; INSERT INTO news_2[title] VALUES['The Gioi Do Day']; INSERT INTO news_2[title] VALUES['Chien Tranh The Gioi II']; INSERT INTO news_2[title] VALUES['Du Hoc Vien'];
Dữ liệu Table news_1:
Dữ liệu trang news_2:
Ok, bây giờ ta làm một số ví dụ để các bạn hiểu rõ hợn lệnh UNION
trong MySQL
này.
Ví dụ 1: Lấy dữ liệu của hai bảng news_1 và news_2 và sau đó gom lại thành một kết quả
SELECT id, title FROM news_1 UNION SELECT id, title FROM news_2
Kết quả:
Ví dụ 2: Lấy ID của bảng news_1, news_2 và sau đó gom lại thành một kết quả
SELECT id FROM news_1 UNION SELECT id FROM news_2
Kết quả:
Rõ ràng UNION
đã bị xóa đi kết quả trùng vì đáng lẽ ra nó phải hiển thị
10 kết quả nhưng ở đây nó hiển thị có 5 kết quả.
Bây giờ ta sử dụng lệnh ALL
để xem thế nào.
SELECT id FROM news_1 UNION ALL SELECT id FROM news_2
Kết quả:
Với lệnh ALL
thì dù bị trùng lặp nhưng nó vẫn trả về kết quả.
3. Lời kết
Toán tử UNION trong MySQL rất ít sử dụng khi xây dựng ứng dụng website mà thay vào
đó sử dụng các lệnh UPDATE
, ADD
và SELECT
nhiều hơn. Bài này cũng tương đối ngắn vì kiến thức đơn giản và dễ hiểu, kể từ bài sau chúng ta tìm hiểu về lệnh JOIN
, đây là một lệnh khá khó đối với những bạn mới học MySQL
.
1] Chức năng của toán tử UNION, UNION ALL
- Trong hệ quản trị cơ sở dữ liệu MySQL, toán tử UNION và UNION ALL được dùng để gộp tập kết quả của hai hay nhiều câu lệnh truy vấn dữ liệu [SELECT] lại với nhau.
- Trong đó:
- Toán tử UNION chỉ lấy mỗi loại giá trị một lần duy nhất [tức là không có trường hợp các giá trị trùng nhau]
- Toán tử UNION ALL sẽ lấy hết tất cả các kết quả, mặc cho chúng có bị trùng nhau hay không.
2] Cách sử dụng toán tử UNION, UNION ALL
- Khi sử dụng toán tử UNION hoặc UNION ALL thì chúng ta cần phải tuân thủ các quy tắc như sau:
- Các câu lệnh SELECT phải có chung số lượng cột.
- Thứ tự cột trong các câu lệnh SELECT phải được sắp xếp theo đúng thứ tự cột của cái bảng kết hợp.
- Các cột tương ứng giữa các câu lệnh SELECT phải có kiểu dữ liệu giống nhau.
- Dưới đây là cú pháp sử dụng toán tử UNION:
SELECT column1, column2, column3, . . . . FROM table1 WHERE condition
UNION
SELECT column1, column2, column3, . . . . FROM table2 WHERE condition;
- Dưới đây là cú pháp sử dụng toán tử UNION ALL:
SELECT column1, column2, column3, . . . . FROM table1 WHERE condition
UNION ALL
SELECT column1, column2, column3, . . . . FROM table2 WHERE condition;
3] Tham khảo một số ví dụ
- Trong bài học này, tôi sẽ sử dụng hai cái bảng Customers & SinhVien như bên dưới để làm ví dụ minh họa.
CustomerID | CustomerName | Gender | Age | City |
1 | Nguyễn Thành Nhân | Nam | 22 | Cần Thơ |
2 | Nguyễn Thụy Tố Quyên | Nữ | 23 | Hậu Giang |
3 | Hồ Nguyễn Minh Thư | Nữ | 25 | Đồng Tháp |
4 | Trương Khắc Tâm | Nam | 20 | Cần Thơ |
MSSV | HoTen | GioiTinh | Tuoi | ThanhPho |
1 | Hồ Nguyễn Minh Thư | Nữ | 19 | An Giang |
2 | Nguyễn Thành Nhân | Nam | 20 | Trà Vinh |
3 | Phạm Khắc Việt | Nam | 18 | Cần Thơ |
- Gộp các khách hàng & sinh viên [sống tại Cần Thơ] vào chung một bảng.
- Lưu ý: Chỉ lấy các thông tin HỌ TÊN, TUỔI, THÀNH PHỐ
SELECT CustomerName, Age, City FROM Customers WHERE City = "Cần Thơ"
UNION ALL
SELECT HoTen, Tuoi, ThanhPho FROM SinhVien WHERE ThanhPho = "Cần Thơ";
- Sau khi thực thi câu lệnh phía trên thì tôi sẽ lấy được một bảng dữ liệu như bên dưới:
CustomerName | Age | City |
Nguyễn Thành Nhân | 22 | Cần Thơ |
Trương Khắc Tâm | 20 | Cần Thơ |
Phạm Khắc Việt | 18 | Cần Thơ |
- Khi chúng ta gộp kết quả từ hai hay nhiều câu lệnh truy vấn dữ liệu [SELECT] lại với nhau thì mặc định tên cột trên cái bảng kết hợp sẽ được lấy từ tên của các cột ở trong câu lệnh truy vấn thứ nhất [điển hình như trong ví dụ 1, tên của các cột là CustomerName, Age, City chứ không phải là HoTen, Tuoi, ThanhPho]
- Để thay đổi tên cột trên bảng kết hợp thì các bạn có thể sử dụng lệnh AS để đặt bí danh cho các cột.
- Ví dụ:
SELECT CustomerName AS C1, Age AS C2, City AS C3 FROM Customers WHERE City = "Cần Thơ"
UNION ALL
SELECT HoTen, Tuoi, ThanhPho FROM SinhVien WHERE ThanhPho = "Cần Thơ";
- Sau khi thực thi câu lệnh phía trên thì tôi sẽ lấy được một bảng dữ liệu như bên dưới:
C1 | C2 | C3 |
Nguyễn Thành Nhân | 22 | Cần Thơ |
Trương Khắc Tâm | 20 | Cần Thơ |
Phạm Khắc Việt | 18 | Cần Thơ |
- Gộp các khách hàng & sinh viên vào chung một bảng.
- Lưu ý: Chỉ lấy HỌ TÊN, TUỔI, THÀNH PHỐ, sắp xếp các kết quả theo thứ tự giảm dần dựa trên độ tuổi.
SELECT CustomerName AS HỌ_TÊN, Age AS TUỔI, City AS THÀNH_PHỐ FROM Customers
UNION ALL
SELECT HoTen, Tuoi, ThanhPho FROM SinhVien
ORDER BY TUỔI DESC;
- Sau khi thực thi câu lệnh phía trên thì tôi sẽ lấy được một bảng dữ liệu như bên dưới:
HỌ_TÊN | TUỔI | THÀNH_PHỐ |
Hồ Nguyễn Minh Thư | 25 | Đồng Tháp |
Nguyễn Thụy Tố Quyên | 23 | Hậu Giang |
Nguyễn Thành Nhân | 22 | Cần Thơ |
Trương Khắc Tâm | 20 | Cần Thơ |
Nguyễn Thành Nhân | 20 | Trà Vinh |
Hồ Nguyễn Minh Thư | 19 | An Giang |
Phạm Khắc Việt | 18 | Cần Thơ |
- Liệt kê tên của tất cả các khách hàng & sinh viên.
- Lưu ý: Họ tên trong cái bảng kết hợp không được phép trùng nhau.
SELECT CustomerName AS HỌ_TÊN FROM Customers
UNION
SELECT HoTen FROM SinhVien;
- Sau khi thực thi câu lệnh phía trên thì tôi sẽ lấy được một bảng dữ liệu như bên dưới:
HỌ_TÊN |
Nguyễn Thành Nhân |
Nguyễn Thụy Tố Quyên |
Hồ Nguyễn Minh Thư |
Trương Khắc Tâm |
Phạm Khắc Việt |
- Gộp các khách hàng & sinh viên vào chung một bảng.
- Lưu ý: Tạo thêm một cột PHÂN_LOẠI để cho biết đó là khách hàng hay sinh viên.
SELECT "Khách hàng" AS PHÂN_LOẠI,
CustomerName AS HỌ_TÊN,
Age AS TUỔI,
City AS THÀNH_PHỐ FROM Customers
UNION
SELECT "Sinh viên", HoTen, Tuoi, ThanhPho FROM SinhVien;
- Sau khi thực thi câu lệnh phía trên thì tôi sẽ lấy được một bảng dữ liệu như bên dưới:
PHÂN_LOẠI | HỌ_TÊN | TUỔI | THÀNH_PHỐ |
Khách hàng | Nguyễn Thành Nhân | 22 | Cần Thơ |
Khách hàng | Nguyễn Thụy Tố Quyên | 23 | Hậu Giang |
Khách hàng | Hồ Nguyễn Minh Thư | 25 | Đồng Tháp |
Khách hàng | Trương Khắc Tâm | 20 | Cần Thơ |
Sinh viên | Hồ Nguyễn Minh Thư | 19 | An Giang |
Sinh viên | Nguyễn Thành Nhân | 20 | Trà Vinh |
Sinh viên | Phạm Khắc Việt | 18 | Cần Thơ |