MySQL 表別名不僅簡化 SQL,更能讓同一張表在單一陳述式中扮演多重角色,解決自我關聯更新/刪除無法用標準 JOIN 處理的難題。本文實戰示範無限分類刪除時的父子關聯遞移更新。
categories 表:cat_id、parent_id(NULL 為頂層)。刪除某分類時,其子分類的 parent_id 需指向被刪除分類的父分類(祖父級)。
LOCK TABLES
`categories` WRITE, -- 原表
`categories` AS `c1` WRITE, -- 子分類角色
`categories` AS `c2` WRITE; -- 父分類角色
UPDATE `categories` AS `c1`, `categories` AS `c2`
SET `c1`.`parent_id` = `c2`.`parent_id`
WHERE `c1`.`parent_id` = `c2`.`cat_id`
AND `c2`.`cat_id` = $cat_id;
DELETE FROM `categories` WHERE `cat_id` = $cat_id;
UNLOCK TABLES;
LOCK TABLES 必須列出原表 + 所有使用的別名。ERROR 1100: Table 'c1' was not locked with LOCK TABLES。| 場景 | 別名角色 | 關鍵點 |
|---|---|---|
| 自我關聯 UPDATE | 來源/目標 | 需鎖定所有別名 |
| 自我關聯 DELETE | 父/子 | 避免外鍵約束衝突 |
| 同表多次 JOIN | 不同路徑 | 簡化欄位引用 |
| 衍生表/子查詢 | 中間結果 | 提升可讀性 |