Trong MySQL, liệt kê 2 bảng trong mệnh đề FROM cách nhau bởi dấu phẩy (FROM table1, table2) tạo ra Cartesian Product (Tích Descartes) — mỗi hàng bảng 1 ghép với mọi hàng bảng 2. Kết quả có số hàng = (số hàng bảng 1) × (số hàng bảng 2). Đây là CROSS JOIN ngầm định.
Ví dụ minh họa
Tạo bảng 1 (chỉ có ID tự tăng):
mysql> CREATE TABLE DemoTable1 (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
Chèn 3 hàng rỗng:
mysql> INSERT INTO DemoTable1 VALUES (), (), ();
Tạo bảng 2 (tên):
mysql> CREATE TABLE DemoTable2 (
FirstName VARCHAR(10)
);
Chèn 3 tên:
mysql> INSERT INTO DemoTable2 VALUES ('Chris'), ('David'), ('Sam');
SELECT từ 2 bảng (Cross Join)
mysql> SELECT Id, FirstName FROM DemoTable1, DemoTable2;
Kết quả (3 × 3 = 9 hàng):
+----+-----------+ | Id | FirstName | +----+-----------+ | 1 | Chris | | 2 | Chris | | 3 | Chris | | 1 | David | | 2 | David | | 3 | David | | 1 | Sam | | 2 | Sam | | 3 | Sam | +----+-----------+
Giải thích
- Mỗi Id (1,2,3) ghép với mỗi FirstName (Chris, David, Sam).
- Không có điều kiện JOIN (
ONhoặcWHERE) → Cartesian Product. - Cú pháp chuẩn SQL:
SELECT ... FROM DemoTable1 CROSS JOIN DemoTable2.
Các loại JOIN phổ biến (so sánh)
| Loại JOIN | Cú pháp | Kết quả |
|---|---|---|
| CROSS JOIN | FROM t1, t2 hoặc CROSS JOIN | Tích Descartes (m × n hàng) |
| INNER JOIN | FROM t1 JOIN t2 ON t1.id = t2.id | Chỉ hàng khớp điều kiện |
| LEFT JOIN | FROM t1 LEFT JOIN t2 ON ... | Tất cả t1 + khớp t2 (NULL nếu không khớp) |
| RIGHT JOIN | FROM t1 RIGHT JOIN t2 ON ... | Tất cả t2 + khớp t1 |
Khi nào dùng CROSS JOIN?
- Tạo dữ liệu test: Kết hợp mọi trường hợp (parameter grid).
- Ma trận, báo cáo pivot: Gom mọi tổ hợp chiều.
- Tính toán toán học trên tập hợp.
⚠️ Cảnh báo
- CROSS JOIN bảng lớn → kết quả khổng lồ (hàng triệu/tỷ hàng) → treo server, hết bộ nhớ.
- Luôn kiểm tra
EXPLAINvà ước lượng số hàng trước khi chạy. - Thường dùng
LIMITcho test:SELECT * FROM t1, t2 LIMIT 10.
Ví dụ thực tế: Tạo lịch làm việc tất cả nhân viên × tất cả ngày trong tháng
SELECT e.EmployeeId, e.Name, d.WorkDate
FROM Employees e
CROSS JOIN (
SELECT DATE('2024-01-01') + INTERVAL n DAY AS WorkDate
FROM Numbers WHERE n < 31
) d
WHERE e.Active = 1;