如何正確地選擇 MySQL 的 JOIN 查詢?
在 MySQL中,JOIN是用于在兩個(gè)或多個(gè)表之間組合行的三種不同的連接類型。那么,JOIN有哪些類型?它們之間有什么區(qū)別?在實(shí)際工作中,我們?cè)撊绾芜x擇呢?這篇文章我們來聊一聊。
一、JOIN類型
MySQL的JOIN查詢,主要包含以下 5種:
- INNER JOIN:內(nèi)連接,結(jié)果返回兩個(gè)表的匹配數(shù)據(jù)。
- LEFT JOIN:也叫LEFT OUTER JOIN左外連接,結(jié)果來自左表,并從右表匹配數(shù)據(jù)。
- RIGHT JOIN:也叫RIGHT OUTER JOIN右外連接,結(jié)果來自右表,并從左表匹配數(shù)據(jù)。
- FULL JOIN:也叫FULL OUTER JOIN完整的外部連接,在匹配數(shù)據(jù)時(shí),兩個(gè)表都來自兩個(gè)表。
- CROSS JOIN:交叉連接,返回兩個(gè)表的笛卡爾積。
下面我們將一一詳細(xì)分析:
1. INNER JOIN
INNER JOIN 返回的是兩個(gè)表中滿足連接條件的記錄,即只顯示兩個(gè)表中匹配的行。
語法:
SELECT 列
FROM 表A
INNER JOIN 表B ON 表A.列 = 表B.列;
示例:假設(shè)有以下兩個(gè)表:
表A:Employees
EmployeeID | Name | DepartmentID |
1 | Alice | 10 |
2 | Bob | 20 |
3 | Carol | NULL |
表B:Departments
DepartmentID | DepartmentName |
10 | HR |
20 | IT |
30 | Finance |
執(zhí)行 INNER JOIN:
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
INNER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
結(jié)果:
Name | DepartmentName |
Alice | HR |
Bob | IT |
說明:Carol 沒有關(guān)聯(lián)的 DepartmentID,因此不在結(jié)果集中。
2. LEFT JOIN
LEFT JOIN 返回左表(第一個(gè)表)中的所有記錄,以及右表中滿足連接條件的記錄。如果右表中沒有匹配的記錄,右表的結(jié)果為 NULL。
語法:
SELECT 列
FROM 表A
LEFT JOIN 表B ON 表A.列 = 表B.列;
示例:使用上述表A 和表B,執(zhí)行 LEFT JOIN:
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
LEFT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
結(jié)果:
Name | DepartmentName |
Alice | HR |
Bob | IT |
Carol | NULL |
說明:Carol 在左表中存在,但在右表中沒有對(duì)應(yīng)的 DepartmentID,因此 DepartmentName 為 NULL。
3. RIGHT JOIN
RIGHT JOIN 返回右表(第二個(gè)表)中的所有記錄,以及左表中滿足連接條件的記錄。如果左表中沒有匹配的記錄,左表的結(jié)果為 NULL。
語法:
SELECT 列
FROM 表A
RIGHT JOIN 表B ON 表A.列 = 表B.列;
示例:使用上述表A 和表B,執(zhí)行 RIGHT JOIN:
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
RIGHT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
結(jié)果:
Name | DepartmentName |
Alice | HR |
Bob | IT |
NULL | Finance |
說明:部門 "Finance" 存在于右表,但在左表中沒有關(guān)聯(lián)的員工,因此 Name 為 NULL。
4. FULL JOIN
FULL JOIN 返回兩個(gè)表中的所有記錄。如果在一個(gè)表中沒有匹配的記錄,另一個(gè)表中的結(jié)果為 NULL。它結(jié)合了 LEFT JOIN 和 RIGHT JOIN 的結(jié)果。
MySQL 中的情況:遺憾的是,MySQL 并不直接支持 FULL OUTER JOIN。要模擬這種行為,可以使用 UNION 來組合 LEFT JOIN 和 RIGHT JOIN 的結(jié)果。
模擬 FULL OUTER JOIN 的語法:
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
LEFT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID
UNION
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
RIGHT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
示例結(jié)果(基于前述表A 和表B):
Name | DepartmentName |
Alice | HR |
Bob | IT |
Carol | NULL |
NULL | Finance |
說明:包括了所有員工和所有部門,不論是否有匹配。
5. CROSS JOIN
CROSS JOIN 返回兩個(gè)表的笛卡爾積,即左表的每一行與右表的每一行組合,生成所有可能的行組合。沒有連接條件。
語法:
SELECT 列
FROM 表A
CROSS JOIN 表B;
示例:使用上述表A(3行)和表B(3行),執(zhí)行 CROSS JOIN:
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
CROSS JOIN Departments;
結(jié)果:
Name | DepartmentName |
Alice | HR |
Alice | IT |
Alice | Finance |
Bob | HR |
Bob | IT |
Bob | Finance |
Carol | HR |
Carol | IT |
Carol | Finance |
說明:總共有 3(Employees) × 3(Departments) = 9 行結(jié)果。
二、總結(jié)
本文,我們分析了 MySQL 中的 5種連接類型
- INNER JOIN:僅返回兩個(gè)表中匹配的記錄。
- LEFT JOIN:返回左表中的所有記錄,以及右表中匹配的記錄;沒有匹配的右表記錄顯示 NULL。
- RIGHT JOIN:返回右表中的所有記錄,以及左表中匹配的記錄;沒有匹配的左表記錄顯示 NULL。
- FULL JOIN:返回兩個(gè)表中的所有記錄;MySQL 需通過 UNION 模擬。
- CROSS JOIN:返回兩個(gè)表的所有可能的行組合(笛卡爾積)。
在實(shí)際工作中,選擇哪種 JOIN 類型取決于具體的數(shù)據(jù)需求和查詢目標(biāo)。理解各類 JOIN 的工作原理有助于編寫高效且準(zhǔn)確的 SQL 查詢。