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

MySQL สร้าง Temporary Table จากผลลัพธ์ SELECT (CREATE TEMPORARY TABLE ... SELECT)

CREATE TEMPORARY TABLE ... AS SELECT

สร้าง Temporary Table และเติมข้อมูลจาก SELECT ในคำสั่งเดียว Temporary Table จะหายอัตโนมัติเมื่อ Session จบ

Syntax

CREATE TEMPORARY TABLE temp_table_name
SELECT column_list FROM source_table WHERE condition;

ตัวอย่าง

CREATE TABLE DemoTable1 (Id INT, Name VARCHAR(100));

INSERT INTO DemoTable1 VALUES
(100, 'John'), (110, 'Chris'), (120, 'Robert'), (130, 'David');

-- สร้าง Temp Table จาก SELECT
CREATE TEMPORARY TABLE DemoTable2 
SELECT * FROM DemoTable1;

ผลลัพธ์: DemoTable2 มีข้อมูลเหมือน DemoTable1 ทุกแถว

+------+--------+
| Id   | Name   |
+------+--------+
| 100  | John   |
| 110  | Chris  |
| 120  | Robert |
| 130  | David  |
+------+--------+

คุณสมบัติ Temporary Table

คุณสมบัติรายละเอียด
Visibilityมองเห็นได้เฉพาะ Session ที่สร้าง (Connection-specific)
Lifetimeหายอัตโนมัติเมื่อ Session จบ (Disconnect) หรือ DROP TEMPORARY TABLE
Name Conflictสามารถชื่อซ้ำ Regular Table ได้ (Temp มี Priority สูงกว่า)
Replicationไม่ Replicate ไป Slave (Statement-based) - ใช้ Row-based
Transactionไม่รองรับ Transaction (DDL Implicit Commit)

ตัวอย่างใช้งานจริง: Intermediate Results

-- Step 1: Filter ข้อมูลใหญ่ลง Temp Table
CREATE TEMPORARY TABLE tmp_active_users AS
SELECT id, email, created_at 
FROM users 
WHERE status = 'active' AND created_at > '2023-01-01';

-- Step 2: Join กับตารางอื่น (เร็วกว่า Subquery)
SELECT u.email, o.total
FROM tmp_active_users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = 'completed';

-- Step 3: Cleanup (Optional - Auto Drop on Disconnect)
DROP TEMPORARY TABLE IF EXISTS tmp_active_users;

⚠️ ข้อจำกัด

  • ไม่รองรับ Foreign Keys
  • ไม่รองรับ Partitioning
  • Memory Engine Default (อาจช้า/เต็ม Memory) - ระบุ Engine: CREATE TEMPORARY TABLE ... ENGINE=InnoDB
  • ใน Stored Procedure: Temp Table หายเมื่อ Procedure จบ (ไม่ใช่ Session)

Alternative: CTE (Common Table Expression) - MySQL 8.0+

WITH active_users AS (
    SELECT id, email FROM users WHERE status = 'active'
)
SELECT u.email, o.total
FROM active_users u
JOIN orders o ON u.id = o.user_id;

ข้อดี CTE: ไม่ต้อง Create/Drop, Readable, Optimizer รวม Query Plan ได้ดีกว่า

เมื่อไหร่ควรใช้ Temp Table แทน CTE

  • Reuse ผลลัพธ์หลายครั้งใน Session เดียว
  • Index บน Intermediate Result (CTE ไม่มี Index)
  • ข้อมูลเยอะมาก ที่ Optimizer Plan ไม่ดี
  • MySQL 5.7 หรือเก่ากว่า