Toán tử UNION ALL trong MySQL
Bùi Tấn Lực
- 896
- 23/09/2025
Chức năng của Toán tử UNION ALL trong MySQL
Toán tử UNION ALL trong MySQL dùng để nối 2 hoặc nhiều câu lệnh select sau đó lấy các cột giống nhau của các bảng và không loại bỏ các hàng trùng lặp, các cột khi select phải có thứ tự giống nhau và kiểu dữ liệu cũng giống nhau, các số lượng cột của các câu lệnh select phải giống nhau.
Code Toán tử UNION ALL trong MySQL
Toán tử UNION ALL một cột trong MySQL
select tinhthanh from tb_daily UNION ALL select tinhthanh from tb_khachhang;
<?php
$dbhost = 'localhost';
$dbuser = 'webmoi_userdata'; // Tên username
$dbpass = 'IhNRcn9n'; // Mật khẩu
// Kết nối đến tên username
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
die('Không kết nối được: ' . mysql_error());
}
// Truy vấn bảng
$sql = "select tinhthanh from tb_daily UNION ALL select tinhthanh from tb_khachhang";
// Chọn tên database
mysql_select_db('webmoi_tendata');
// Xét kiểu tiếng việt
mysql_query('SET NAMES "utf8"');
// Kết quả truy vấn trả về mảng
$ketqua = mysql_query($sql,$conn);
if(!$ketqua){
die('Không thể lấy dữ liệu: ' . mysql_error());
}
// Dùng vòng lặp để lấy ra từng hàng trong bảng
while($row = mysql_fetch_array($ketqua, MYSQL_ASSOC)){
echo "Tỉnh/Thành: {$row['tinhthanh']} <br> ".
"--------------------------------<br>";
}
// Đóng kết nối database
mysql_close($conn);
?>
Kết quả:
Tỉnh/Thành: Hồ Chí Minh
--------------------------------
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tỉnh/Thành: Đà Nẳng
--------------------------------
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Toán tử UNION ALL hai cột trong MySQL
select xaphuong,tinhthanh from tb_daily UNION ALL select xaphuong,tinhthanh from tb_khachhang;
<?php
$dbhost = 'localhost';
$dbuser = 'webmoi_userdata'; // Tên username
$dbpass = 'IhNRcn9n'; // Mật khẩu
// Kết nối đến tên username
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
die('Không kết nối được: ' . mysql_error());
}
// Truy vấn bảng
$sql = "select xaphuong,tinhthanh from tb_daily UNION ALL select xaphuong,tinhthanh from tb_khachhang";
// Chọn tên database
mysql_select_db('webmoi_tendata');
// Xét kiểu tiếng việt
mysql_query('SET NAMES "utf8"');
// Kết quả truy vấn trả về mảng
$ketqua = mysql_query($sql,$conn);
if(!$ketqua){
die('Không thể lấy dữ liệu: ' . mysql_error());
}
// Dùng vòng lặp để lấy ra từng hàng trong bảng
while($row = mysql_fetch_array($ketqua, MYSQL_ASSOC)){
echo "Xã/Phường: {$row['xaphuong']} <br> ".
"Tỉnh/Thành: {$row['tinhthanh']} <br> ".
"--------------------------------<br>";
}
// Đóng kết nối database
mysql_close($conn);
?>
Kết quả:
Xã/Phường: Tân Vĩnh Lộc
Tỉnh/Thành: Hồ Chí Minh
--------------------------------
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Xã/Phường: Đông Dương
Tỉnh/Thành: Đà Nẳng
--------------------------------
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Toán tử UNION ALL ba cột trong MySQL
select ten,xaphuong,tinhthanh from tb_daily UNION ALL select ten,xaphuong,tinhthanh from tb_khachhang;
<?php
$dbhost = 'localhost';
$dbuser = 'webmoi_userdata'; // Tên username
$dbpass = 'IhNRcn9n'; // Mật khẩu
// Kết nối đến tên username
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
die('Không kết nối được: ' . mysql_error());
}
// Truy vấn bảng
$sql = "select ten,xaphuong,tinhthanh from tb_daily UNION ALL select ten,xaphuong,tinhthanh from tb_khachhang";
// Chọn tên database
mysql_select_db('webmoi_tendata');
// Xét kiểu tiếng việt
mysql_query('SET NAMES "utf8"');
// Kết quả truy vấn trả về mảng
$ketqua = mysql_query($sql,$conn);
if(!$ketqua){
die('Không thể lấy dữ liệu: ' . mysql_error());
}
// Dùng vòng lặp để lấy ra từng hàng trong bảng
while($row = mysql_fetch_array($ketqua, MYSQL_ASSOC)){
echo "Tên: {$row['ten']} <br> ".
"Xã/Phường: {$row['xaphuong']} <br> ".
"Tỉnh/Thành: {$row['tinhthanh']} <br> ".
"--------------------------------<br>";
}
// Đóng kết nối database
mysql_close($conn);
?>
Kết quả:
Tên: Bùi Tấn Lực
Xã/Phường: Tân Vĩnh Lộc
Tỉnh/Thành: Hồ Chí Minh
--------------------------------
Tên: Trần Thị Vân
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên: Nguyễn Thùy Dung
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên: Bùi Thị Nhím
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên: Nguyễn Thị Cherry
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên: Bùi Đan Trúc Quỳnh
Xã/Phường: Đông Dương
Tỉnh/Thành: Đà Nẳng
--------------------------------
Tên: Nguyễn Thảo Nhật Hạ
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Toán tử UNION ALL phân bảng trong MySQL
Ở đây mình dùng AS để đặt tên cứng cho cột lấy ra, tên cứng đó sẽ theo từng hàng của mỗi bảng:
select 'Đại lý' AS tenbang,ten,xaphuong,tinhthanh from tb_daily UNION ALL select 'Khách hàng' AS tenbang,ten,xaphuong,tinhthanh from tb_khachhang;
<?php
$dbhost = 'localhost';
$dbuser = 'webmoi_userdata'; // Tên username
$dbpass = 'IhNRcn9n'; // Mật khẩu
// Kết nối đến tên username
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn ){
die('Không kết nối được: ' . mysql_error());
}
// Truy vấn bảng
$sql = "select 'Đại lý' AS tenbang,ten,xaphuong,tinhthanh from tb_daily UNION ALL select 'Khách hàng' AS tenbang,ten,xaphuong,tinhthanh from tb_khachhang";
// Chọn tên database
mysql_select_db('webmoi_tendata');
// Xét kiểu tiếng việt
mysql_query('SET NAMES "utf8"');
// Kết quả truy vấn trả về mảng
$ketqua = mysql_query($sql,$conn);
if(!$ketqua){
die('Không thể lấy dữ liệu: ' . mysql_error());
}
// Dùng vòng lặp để lấy ra từng hàng trong bảng
while($row = mysql_fetch_array($ketqua, MYSQL_ASSOC)){
echo "Tên Bảng: {$row['tenbang']} <br> ".
"Tên: {$row['ten']} <br> ".
"Xã/Phường: {$row['xaphuong']} <br> ".
"Tỉnh/Thành: {$row['tinhthanh']} <br> ".
"--------------------------------<br>";
}
// Đóng kết nối database
mysql_close($conn);
?>
Kết quả:
Tên Bảng: Đại lý
Tên: Bùi Tấn Lực
Xã/Phường: Tân Vĩnh Lộc
Tỉnh/Thành: Hồ Chí Minh
--------------------------------
Tên Bảng: Đại lý
Tên: Trần Thị Vân
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên Bảng: Đại lý
Tên: Nguyễn Thùy Dung
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên Bảng: Đại lý
Tên: Bùi Thị Nhím
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên Bảng: Đại lý
Tên: Nguyễn Thị Cherry
Xã/Phường: Long Phụng
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Tên Bảng: Khách hàng
Tên: Bùi Đan Trúc Quỳnh
Xã/Phường: Đông Dương
Tỉnh/Thành: Đà Nẳng
--------------------------------
Tên Bảng: Khách hàng
Tên: Nguyễn Thảo Nhật Hạ
Xã/Phường: Mỏ Cày
Tỉnh/Thành: Quảng Ngãi
--------------------------------
Kinh nghiệm sử dụng UNION ALL trong MySQL hiệu quả
Việc kết hợp nhiều tập dữ liệu không chỉ phụ thuộc vào cú pháp truy vấn mà còn cần chọn đúng cách xử lý dữ liệu. Khi sử dụng UNION ALL, nên xác định rõ mục đích lấy dữ liệu, kiểm tra sự tương đồng giữa các bảng và tránh thực hiện những thao tác dư thừa làm tăng thời gian xử lý.
Khi nào nên dùng UNION ALL thay vì UNION?
Nên ưu tiên UNION ALL khi cần giữ nguyên toàn bộ kết quả từ các truy vấn thành phần, bao gồm cả những dòng có giá trị giống nhau. Cách này đặc biệt phù hợp khi dữ liệu đến từ các bảng hoặc nguồn khác nhau và mỗi dòng đều có ý nghĩa riêng.
Khác với UNION, UNION ALL không cần bước loại bỏ các dòng trùng lặp. Vì vậy, trong trường hợp không có yêu cầu loại dữ liệu trùng, lựa chọn này thường đơn giản và phù hợp hơn.
SELECT customer_id, amount
FROM orders_2025
UNION ALL
SELECT customer_id, amount
FROM orders_2026;
Ví dụ trên có thể giữ lại cả những bản ghi giống nhau giữa hai bảng. Nếu mục tiêu là tổng hợp toàn bộ dữ liệu của hai nguồn mà không cần loại trùng, UNION ALL là lựa chọn hợp lý.
Kiểm tra dữ liệu trước khi kết hợp bằng UNION ALL
Trước khi ghép kết quả, cần kiểm tra các truy vấn có cùng số lượng cột và các cột ở cùng vị trí có kiểu dữ liệu tương thích. Đồng thời, nên xem xét ý nghĩa của từng cột để tránh kết hợp những dữ liệu có cấu trúc giống nhau nhưng bản chất khác nhau.
Chẳng hạn, nếu hai truy vấn đều trả về mã sản phẩm và số lượng, thứ tự cột cần được thống nhất:
SELECT product_id, quantity
FROM warehouse_a
UNION ALL
SELECT product_id, quantity
FROM warehouse_b;
Ngoài cấu trúc cột, cũng nên kiểm tra dữ liệu thực tế trước khi kết hợp. Điều này giúp phát hiện sớm các trường hợp giá trị NULL, kiểu dữ liệu không đồng nhất hoặc bản ghi trùng lặp ngoài dự kiến.
Tối ưu truy vấn khi sử dụng UNION ALL với nhiều bảng
Khi phải kết hợp dữ liệu từ nhiều bảng, nên lọc những bản ghi cần thiết ngay trong từng truy vấn thay vì lấy toàn bộ dữ liệu rồi mới xử lý ở bước sau. Điều này giúp giảm số lượng dòng phải đưa vào tập kết quả cuối cùng.
SELECT customer_id, amount
FROM orders_2025
WHERE status = 'completed'
UNION ALL
SELECT customer_id, amount
FROM orders_2026
WHERE status = 'completed';
Nếu các truy vấn thành phần sử dụng điều kiện lọc hoặc cột thường xuyên tìm kiếm, việc thiết kế chỉ mục phù hợp cho từng bảng cũng có thể hỗ trợ quá trình truy vấn. Với số lượng bảng lớn, nên kiểm tra kế hoạch thực thi để xác định phần nào đang tiêu tốn nhiều tài nguyên thay vì tối ưu theo phỏng đoán.
Một nguyên tắc đơn giản là chỉ lấy những cột thực sự cần thiết, đặt điều kiện lọc phù hợp ở từng nguồn dữ liệu và chỉ dùng UNION ALL khi việc giữ lại các dòng trùng là đúng với yêu cầu nghiệp vụ.
Lời kết
Cảm ơn các bạn đã tham khảo bài viết Toán tử UNION ALL trong MySQL.
Tải file database .sql về nếu muốn kiểm tra hoặc thực hành Tải về.
- 0 Bình luận
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *