萬盛學電腦網

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

MySQL 多表關聯查詢與多表關聯刪除實戰指南

多表關聯是關係型資料庫的核心能力。本文系統講解 LEFT JOIN、INNER JOIN、RIGHT JOIN 的語法差異、執行邏輯,並重點演示 **多表關聯刪除** 的標準寫法與避坑指南。

JOIN 類型語法與語義對比

JOIN 類型語法結果集適用場景
INNER JOINA INNER JOIN B ON A.id = B.id僅返回**雙方都匹配**的行主從表強關聯,如訂單-訂單項
LEFT JOINA LEFT JOIN B ON A.id = B.id返回**左表所有行**,右表無匹配則 NULL主表必須保留,如用戶-訂單(無訂單用戶也要查出)
RIGHT JOINA RIGHT JOIN B ON A.id = B.id返回**右表所有行**,左表無匹配則 NULL較少用,可改寫為 LEFT JOIN 互換表順序
FULL JOINMySQL 不支援雙方所有行,無匹配填 NULL用 LEFT JOIN UNION RIGHT JOIN 模擬

LEFT JOIN 實戰範例


-- 建表
CREATE TABLE `product` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `amount` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

CREATE TABLE `product_details` (
  `id` int(10) unsigned NOT NULL,
  `weight` int(10) unsigned DEFAULT NULL,
  `exist` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

-- 測試資料
INSERT INTO product (id, amount) VALUES (1,100),(2,200),(3,300),(4,400);
INSERT INTO product_details (id, weight, exist) VALUES (2,22,0),(4,44,1),(5,55,0),(6,66,1);

-- 查詢:所有產品 + 明細(無明細顯示 NULL)
SELECT p.id, p.amount, pd.weight, pd.exist
FROM product p
LEFT JOIN product_details pd ON p.id = pd.id;

結果


+----+--------+--------+------+
| id | amount | weight | exist|
+----+--------+--------+------+
|  1 |    100 |   NULL | NULL |
|  2 |    200 |     22 |    0 |
|  3 |    300 |   NULL | NULL |
|  4 |    400 |     44 |    1 |
+----+--------+--------+------+

注意:product_details 中 id=5,6 在 product 中不存在,**LEFT JOIN 不會顯示**(因以左表為基準)。若需雙向保留,用 FULL JOIN 模擬。

多表關聯刪除:標準語法與陷阱

標準語法(MySQL 專有擴展)


-- 刪除 category 表中 id=1 的分類,同時刪除 news 表中對應的文章
DELETE c, n
FROM category c
LEFT JOIN news n ON c.id = n.category_id
WHERE c.id = 1;

關鍵規則

  1. DELETE 後列出要刪除的表別名:DELETE c, n 表示同時刪除兩表匹配行;DELETE c 僅刪除主表。
  2. JOIN 類型決定刪除範圍:
    • INNER JOIN:僅刪除**雙方都存在**的匹配行。
    • LEFT JOIN:刪除**左表所有符合 WHERE 的行**,右表**有匹配則一併刪除**,無匹配則不影響右表。
  3. WHERE 條件僅能引用左表(或驅動表)欄位,右表條件放 ON 子句。

對比:REPLACE INTO vs INSERT ... ON DUPLICATE KEY UPDATE

刪除重插(REPLACE)會導致自增 ID 變更、外鍵級聯、觸發器雙重觸發。**多表關聯刪除 + 單獨 INSERT** 更可控。

INNER JOIN 等值查詢範例


SELECT c.nom, e.nom
FROM consultant c
INNER JOIN affaire a ON c.consultant_id = a.consultant_id
INNER JOIN besoin b ON a.besoin_id = b.besoin_id
INNER JOIN salarie sa ON b.salarie_id = sa.salarie_id
INNER JOIN site s ON sa.site_id = s.site_id
INNER JOIN entreprise e ON s.entreprise_id = e.entreprise_id;

等價於舊式逗號連接 + WHERE,但語義更清晰、優化器更易產生最佳計劃。

效能優化提示

  • 驅動表(左表/前表)應為小結果集:優化器通常選擇小表驅動大表,但可用 STRAIGHT_JOIN 強制順序。
  • ON 條件欄位必須有索引:被驅動表的關聯欄位建立索引,否則全表掃描。
  • 避免 SELECT *:只取需要欄位,減少網路傳輸、回表、臨時表大小。
  • 大表關聯考慮分頁/分批:LIMIT 下推、游標分頁。
copyright © 萬盛學電腦網 all rights reserved