Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Nối hai bảng trong MySQL với điều kiện (UNION ALL)?

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ểmUNIONUNION ALL
DuplicateLoại bỏ (DISTINCT)Giữ tất cả
Hiệu năngChậm (sort/unique)Nhanh (chỉ append)
Số cộtPhải giống nhauPhải giống nhau
Kiểu dữ liệuTương thíchTương thích

Yêu cầu UNION

  1. Số cột SELECT giống nhau
  2. Kiểu dữ liệu cột tương ứng tương thích
  3. 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