Giải pháp: UNION ALL với WHERE
UNION ALL nối kết quả nhiều SELECT, giữ duplicate (khác UNION loại bỏ trùng). Mỗi SELECT có thể có WHERE riêng.
Ví dụ minh họa
Tạo 2 bảng
mysql> CREATE TABLE DemoTable1 (Id INT, FirstName VARCHAR(20)); mysql> INSERT INTO DemoTable1 VALUES(10, 'John'), (20, 'Carol'); mysql> CREATE TABLE DemoTable2 (Id INT, FirstName VARCHAR(20)); mysql> INSERT INTO DemoTable2 VALUES(20, 'David'), (40, 'Chris');
Dữ liệu bảng 1
+------+-----------+ | Id | FirstName | +------+-----------+ | 10 | John | | 20 | Carol | +------+-----------+
Dữ liệu bảng 2
+------+-----------+ | Id | FirstName | +------+-----------+ | 20 | David | | 40 | Chris | +------+-----------+
Truy vấn UNION ALL có điều kiện
mysql> SELECT * FROM DemoTable1 WHERE Id = 20
-> UNION ALL
-> SELECT * FROM DemoTable2 WHERE Id = 20;
Kết quả
+------+-----------+ | Id | FirstName | +------+-----------+ | 20 | Carol | | 20 | David | +------+-----------+
UNION vs UNION ALL
| Đặc điểm | UNION | UNION ALL |
|---|---|---|
| Duplicate | Loại bỏ (DISTINCT) | Giữ tất cả |
| Hiệu năng | Chậm (sort/unique) | Nhanh (chỉ append) |
| Số cột | Phải giống nhau | Phải giống nhau |
| Kiểu dữ liệu | Tương thích | Tương thích |
Yêu cầu UNION
- Số cột SELECT giống nhau
- Kiểu dữ liệu cột tương ứng tương thích
- Thứ tự cột phải khớp (không dùng tên cột)
Best Practice: Cột tường minh
SELECT Id, FirstName FROM DemoTable1 WHERE Id = 20 UNION ALL SELECT Id, FirstName FROM DemoTable2 WHERE Id = 20;
Tránh SELECT * trong UNION (rủi ro schema thay đổi).
Mở rộng: Thêm cột nguồn
SELECT Id, FirstName, 'Table1' AS source FROM DemoTable1 WHERE Id = 20 UNION ALL SELECT Id, FirstName, 'Table2' AS source FROM DemoTable2 WHERE Id = 20;
Kết quả
+------+-----------+--------+ | Id | FirstName | source | +------+-----------+--------+ | 20 | Carol | Table1 | | 20 | David | Table2 | +------+-----------+--------+
Lưu ý
- ORDER BY/LIMIT áp dụng cho kết quả cuối cùng (cần wrap trong subquery)
- MySQL 8.0+: Hỗ trợ CTE (WITH) để viết rõ ràng hơn