Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL สร้าง Combination ทุกคู่ของค่าจากตารางเดียว (Cross Join)

Cross Join (Cartesian Product) สร้างทุกชุดค่าที่เป็นไปได้

ใช้ Comma Join (Implicit Cross Join) หรือ CROSS JOIN Keyword เพื่อจับคู่ทุกแถวจากทุกตารางที่ระบุ

ตัวอย่าง: สร้าง Combination ของ Value1 และ Value2

CREATE TABLE DemoTable622 (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Value1 INT, Value2 INT
);

INSERT INTO DemoTable622(Value1, Value2) VALUES
(1000, 1000), (2000, 3000);

Query: Cross Join ตารางกับตัวเอง 3 ครั้ง

SELECT tbl1.Id, tbl2.Value1, tbl3.Value2
FROM DemoTable622 tbl1, DemoTable622 tbl2, DemoTable622 tbl3;

ผลลัพธ์: 2 × 2 × 2 = 8 แถว

+----+--------+--------+
| Id | Value1 | Value2 |
+----+--------+--------+
| 1  | 1000   | 1000   |
| 2  | 1000   | 1000   |
| 1  | 2000   | 1000   |
| 2  | 2000   | 1000   |
| 1  | 1000   | 3000   |
| 2  | 1000   | 3000   |
| 1  | 2000   | 3000   |
| 2  | 2000   | 3000   |
+----+--------+--------+

Syntax Comparison

Syntaxตัวอย่างหมายเหตุ
Implicit (Comma)FROM t1, t2, t3Old Style, ไม่แนะนำ
Explicit CROSS JOINFROM t1 CROSS JOIN t2 CROSS JOIN t3ANSI Standard, ชัดเจนกว่า
INNER JOIN (No ON)FROM t1 INNER JOIN t2เทียบเท่า CROSS JOIN

กรณีใช้งานจริง

  • Test Data Generation: สร้างข้อมูลทดสอบทุก Combination
  • Matrix/Grid: สร้าง Grid พิกัด (x, y)
  • Parameter Sweep: ทดสอบทุกชุด Parameter
  • Reporting: แสดงสินค้าทุกชนิด x สาขาทุกสาขา (แม้ยอดขาย = 0)

⚠️ ข้อควรระวัง: Explosion

100 rows × 100 rows × 100 rows = 1,000,000 rows - อาจทำให้ Memory/Temp Table เต็ม

-- จำกัดด้วย WHERE (ทำให้กลายเป็น Inner Join)
SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.id = t3.id;

-- หรือ LIMIT
SELECT * FROM t1 CROSS JOIN t2 LIMIT 1000;

ตัวอย่าง: สร้างปฏิทิน 1 ปี × 24 ชั่วโมง

WITH dates AS (
    SELECT DATE('2024-01-01') + INTERVAL n DAY AS dt
    FROM (SELECT 0 n UNION SELECT 1 UNION SELECT 2 ... UNION SELECT 364) nums
),
hours AS (
    SELECT 0 h UNION SELECT 1 UNION SELECT 2 ... UNION SELECT 23
)
SELECT d.dt, h.h FROM dates d CROSS JOIN hours h
ORDER BY d.dt, h.h;