在 MySQL 中,“連接(JOIN)” 是用于將多個表的數據按指定條件關聯查詢的核心操作,通過關聯不同表中相關聯的字段(如主鍵與外鍵),可以一次性獲取來自多個表的組合數據。以下是 MySQL 中常用的連接類型及使用方法:
連接的本質是通過 關聯字段(如 user.id 和 order.user_id)將多個表 “拼接” 起來,關聯字段通常是一個表的主鍵(唯一標識)和另一個表的外鍵(引用前者的字段)。
核心語法結構:
SELECT 字段列表
FROM 表1
[連接類型] JOIN 表2
ON 表1.關聯字段 = 表2.關聯字段
[WHERE 過濾條件];
-
ON 子句:指定連接條件(必選),定義兩個表如何關聯;
-
連接類型:決定如何處理 “不滿足連接條件” 的記錄(不同連接類型結果不同)。
假設有以下兩張表用于示例:
-
user 表(用戶信息):id(主鍵)、name(姓名)
-
order 表(訂單信息):id(訂單 ID)、user_id(外鍵,關聯 user.id)、amount(金額)
作用:僅返回兩個表中 滿足連接條件 的記錄(即 “交集” 部分)。
語法:
SELECT 表1.字段, 表2.字段
FROM 表1
INNER JOIN 表2
ON 表1.關聯字段 = 表2.關聯字段;
(INNER 可省略,直接寫 JOIN)
示例:查詢 “有訂單的用戶” 及其訂單信息(只顯示有匹配的用戶和訂單):
SELECT
u.id AS 用戶ID,
u.name AS 用戶名,
o.id AS 訂單ID,
o.amount AS 訂單金額
FROM
user u
INNER JOIN
`order` o
ON
u.id = o.user_id;
結果特點:
-
只包含 “有訂單的用戶” 和 “屬于這些用戶的訂單”;
-
沒有訂單的用戶(
user 表中無匹配 order 記錄)不會顯示;
-
沒有對應用戶的訂單(
order.user_id 無效)也不會顯示。
作用:返回 左表的所有記錄,以及右表中滿足連接條件的記錄;若右表無匹配,右表字段顯示 NULL。
語法:
SELECT 字段列表
FROM 左表
LEFT JOIN 右表
ON 左表.關聯字段 = 右表.關聯字段;
(LEFT JOIN 也可寫為 LEFT OUTER JOIN,OUTER 可省略)
示例:查詢 “所有用戶” 及其訂單信息(包括沒有訂單的用戶):
SELECT
u.id AS 用戶ID,
u.name AS 用戶名,
o.id AS 訂單ID,
o.amount AS 訂單金額
FROM
user u
LEFT JOIN
`order` o
ON
u.id = o.user_id;
結果特點:
-
左表(
user)的所有用戶都會顯示;
-
有訂單的用戶:顯示對應的訂單信息;
-
無訂單的用戶:訂單相關字段(
o.id、o.amount)顯示 NULL。
作用:與左連接相反,返回 右表的所有記錄,以及左表中滿足連接條件的記錄;若左表無匹配,左表字段顯示 NULL。
語法:
SELECT 字段列表
FROM 左表
RIGHT JOIN 右表
ON 左表.關聯字段 = 右表.關聯字段;
(RIGHT JOIN 也可寫為 RIGHT OUTER JOIN)
示例:查詢 “所有訂單” 及對應的用戶信息(包括無效用戶的訂單):
SELECT
u.id AS 用戶ID,
u.name AS 用戶名,
o.id AS 訂單ID,
o.amount AS 訂單金額
FROM
user u
RIGHT JOIN
`order` o
ON
u.id = o.user_id;
結果特點:
-
右表(
order)的所有訂單都會顯示;
-
有對應用戶的訂單:顯示用戶信息;
-
無對應用戶的訂單(如
user_id 不存在):用戶相關字段(u.id、u.name)顯示 NULL。
作用:返回左表和右表的所有記錄,匹配的記錄合并,不匹配的部分用 NULL 填充(即 “左連接 + 右連接” 的并集)。
注意:MySQL 不直接支持 FULL JOIN,需用 UNION 組合左連接和右連接的結果實現:
SELECT u.id, u.name, o.id, o.amount
FROM user u
LEFT JOIN `order` o ON u.id = o.user_id
UNION
SELECT u.id, u.name, o.id, o.amount
FROM user u
RIGHT JOIN `order` o ON u.id = o.user_id
WHERE u.id IS NULL;
結果特點:包含所有用戶和所有訂單,無論是否匹配。
通過連續使用 JOIN 可關聯多張表,例如關聯 user(用戶)、order(訂單)、product(商品):
SELECT
u.name AS 用戶名,
o.id AS 訂單ID,
p.name AS 商品名
FROM
user u
JOIN
`order` o ON u.id = o.user_id
JOIN
product p ON o.product_id = p.id;
-
ON:僅用于 指定連接條件,過濾 “表之間如何關聯”,不影響表本身的記錄數(左 / 右連接中,不滿足 ON 條件的記錄會保留,用 NULL 填充);
-
WHERE:用于 過濾連接后的結果,會直接排除不滿足條件的記錄。
示例對比:
SELECT u.name, o.amount
FROM user u
LEFT JOIN `order` o
ON u.id = o.user_id AND o.amount > 100;
SELECT u.name, o.amount
FROM user u
LEFT JOIN `order` o ON u.id = o.user_id
WHERE o.amount > 100;
將一張表當作兩張表來關聯(需用別名區分),常用于查詢 “表中存在層級關系” 的數據(如員工表中 “員工” 與 “上級”)。
示例:employee 表(id、name、manager_id(上級 ID,關聯自身 id)),查詢每個員工及其上級姓名:
SELECT
e.name AS 員工姓名,
m.name AS 上級姓名
FROM
employee e
LEFT JOIN
employee m
ON
e.manager_id = m.id;
-
關聯字段索引:連接的關聯字段(如
user.id、order.user_id)建議創建索引,否則大表連接會導致全表掃描,性能極差。
-
表別名:多表連接時務必使用別名(如
u、o),簡化 SQL 并避免字段名沖突(如 user.id 和 order.id)。
-
避免笛卡爾積:若忘記寫
ON 條件,會產生 “笛卡爾積”(左表每行與右表每行都匹配),導致結果集過大(如 1000 行 × 1000 行 = 100 萬行),務必注意。
-
優先內連接:內連接性能通常優于外連接(因需處理的記錄更少),非必要不使用外連接。
通過合理使用連接,可以高效地從多個表中整合數據,是 MySQL 查詢中不可或缺的技能。實際開發中,需根據業務需求選擇合適的連接類型,并注意索引優化以提升性能。