如何正确地选择 MySQL的JOIN查询?

你好,我是猿java。

在 MySQL中,JOIN是用于在两个或多个表之间组合行的三种不同的连接类型。那么,JOIN有哪些类型?它们之间有什么区别?在实际工作中,我们该如何选择呢?这篇文章我们来聊一聊。

1. JOIN类型

MySQL的JOIN查询,主要包含以下 5种:

  1. INNER JOIN:内连接,结果返回两个表的匹配数据。
  2. LEFT JOIN:也叫LEFT OUTER JOIN左外连接,结果来自左表,并从右表匹配数据。
  3. RIGHT JOIN:也叫RIGHT OUTER JOIN右外连接,结果来自右表,并从左表匹配数据。
  4. FULL JOIN:也叫FULL OUTER JOIN完整的外部连接,在匹配数据时,两个表都来自两个表。
  5. CROSS JOIN:交叉连接,返回两个表的笛卡尔积。

MySQL JOIN

下面我们将一一详细分析:

1.1 INNER JOIN

INNER JOIN 返回的是两个表中满足连接条件的记录,即只显示两个表中匹配的行。

语法:

1
2
3
SELECT
FROM 表A
INNER JOIN 表B ON 表A.列 = 表B.列;

示例:
假设有以下两个表:

表A:Employees

EmployeeID Name DepartmentID
1 Alice 10
2 Bob 20
3 Carol NULL

表B:Departments

DepartmentID DepartmentName
10 HR
20 IT
30 Finance

执行 INNER JOIN

1
2
3
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
INNER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;

结果:

Name DepartmentName
Alice HR
Bob IT

说明:
Carol 没有关联的 DepartmentID,因此不在结果集中。

1.2 LEFT JOIN

LEFT JOIN 返回左表(第一个表)中的所有记录,以及右表中满足连接条件的记录。如果右表中没有匹配的记录,右表的结果为 NULL

语法:

1
2
3
SELECT
FROM 表A
LEFT JOIN 表B ON 表A.列 = 表B.列;

示例:
使用上述表A 和表B,执行 LEFT JOIN

1
2
3
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
LEFT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;

结果:

Name DepartmentName
Alice HR
Bob IT
Carol NULL

说明:
Carol 在左表中存在,但在右表中没有对应的 DepartmentID,因此 DepartmentNameNULL

1.3 RIGHT JOIN

RIGHT JOIN 返回右表(第二个表)中的所有记录,以及左表中满足连接条件的记录。如果左表中没有匹配的记录,左表的结果为 NULL

语法:

1
2
3
SELECT
FROM 表A
RIGHT JOIN 表B ON 表A.列 = 表B.列;

示例:
使用上述表A 和表B,执行 RIGHT JOIN

1
2
3
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
RIGHT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;

结果:

Name DepartmentName
Alice HR
Bob IT
NULL Finance

说明:
部门 “Finance” 存在于右表,但在左表中没有关联的员工,因此 NameNULL

1.4 FULL JOIN

FULL JOIN 返回两个表中的所有记录。如果在一个表中没有匹配的记录,另一个表中的结果为 NULL。它结合了 LEFT JOINRIGHT JOIN 的结果。

MySQL 中的情况:
遗憾的是,MySQL 并不直接支持 FULL OUTER JOIN。要模拟这种行为,可以使用 UNION 来组合 LEFT JOINRIGHT JOIN 的结果。

模拟 FULL OUTER JOIN 的语法:

1
2
3
4
5
6
7
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;

示例结果(基于前述表A 和表B):

Name DepartmentName
Alice HR
Bob IT
Carol NULL
NULL Finance

说明:
包括了所有员工和所有部门,不论是否有匹配。

1.5. CROSS JOIN

CROSS JOIN 返回两个表的笛卡尔积,即左表的每一行与右表的每一行组合,生成所有可能的行组合。没有连接条件。

语法:

1
2
3
SELECT
FROM 表A
CROSS JOIN 表B;

示例:
使用上述表A(3行)和表B(3行),执行 CROSS JOIN

1
2
3
SELECT Employees.Name, Departments.DepartmentName
FROM Employees
CROSS JOIN Departments;

结果:

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 行结果。

2. 总结

本文,我们分析了 MySQL 中的 5种连接类型

  • INNER JOIN:仅返回两个表中匹配的记录。
  • LEFT JOIN:返回左表中的所有记录,以及右表中匹配的记录;没有匹配的右表记录显示 NULL
  • RIGHT JOIN:返回右表中的所有记录,以及左表中匹配的记录;没有匹配的左表记录显示 NULL
  • FULL JOIN:返回两个表中的所有记录;MySQL 需通过 UNION 模拟。
  • CROSS JOIN:返回两个表的所有可能的行组合(笛卡尔积)。

在实际工作中,选择哪种 JOIN 类型取决于具体的数据需求和查询目标。理解各类 JOIN 的工作原理有助于编写高效且准确的 SQL 查询。

3. 学习交流

如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注公众号:猿java,持续输出硬核文章。

drawing