Hướng dẫn dùng typing union trong PHP

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.

Hướng dẫn dùng typing union trong PHP

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, ADDSELECT 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ử UNIONUNION 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ơ