萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL INSERT INTO SELECT 進階用法:多表 JOIN 組合字段插入、派生表別名陷阱、VALUES 禁用

基本語法

INSERT INTO db1 (col1, col2) SELECT col1, col2 FROM db2;
  • 適用於「單表 → 單表」欄位對應複製。
  • 欄位順序、數量、型別必須一一對應。

多表來源:先 JOIN 再插入(關鍵:派生表必須有別名)

-- 錯誤:缺少別名
INSERT INTO a (f1, f2) SELECT * FROM (SELECT b.f1, c.f2 FROM b JOIN c);

-- 正確:給子查詢起別名 AS tb
INSERT INTO a (f1, f2) SELECT * FROM (SELECT b.f1, c.f2 FROM b JOIN c) AS tb;

錯誤碼:ERROR 1248 (42000): Every derived TABLE must have its own alias

常見錯誤:誤加 VALUES

-- 錯誤
INSERT INTO db1 (f1, f2) VALUES SELECT f1, f2 FROM db2;
-- ERROR: You have an error in your SQL syntax
  • INSERT ... VALUES 只能接常數列表,不能接子查詢。
  • INSERT ... SELECT 直接接查詢,**不寫 VALUES**。

完整實戰範例

-- 將「訂單表」與「用戶表」關聯後的精簡資料,寫入「報表表」
INSERT INTO rpt_order_summary (order_id, user_name, order_amt, create_time)
SELECT o.id, u.name, o.amount, o.created_at
FROM orders o
INNER JOIN users u ON o.user_id = u.id
WHERE o.status = 'paid'
  AND o.created_at >= '2024-01-01';

效能優化建議

  • 分批提交:大量資料用 LIMIT 分批,避免長事務、大 binlog。
  • 覆蓋索引:來源表查詢欄位若被覆蓋索引覆蓋,可避免回表。
  • 關閉 binlog:非複寫環境 SET sql_log_bin=0 加速導入。
  • 考慮 LOAD DATA:極大量級(億級)優先用 LOAD DATA INFILE。

總結

INSERT INTO ... SELECT 是跨表複製利器。核心口訣:派生表必須有別名、別寫 VALUES、欄位順序對齊、大量分批。多表來源先 JOIN 成虛擬表再 SELECT,邏輯清晰且效能可控。

copyright © 萬盛學電腦網 all rights reserved