在关系型数据库中,连接(JOIN)是一种在查询中组合来自两个或多个表的行的方法。这些表通过一个或多个列中的相关值关联起来。SQL 提供了几种类型的连接,每种连接在处理表之间的关系和数据检索时都有其特定的方式。最常见的连接类型是内连接(INNER JOIN)、左连接(LEFT JOIN 或 LEFT OUTER JOIN)和右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)。
1. 内连接(INNER JOIN)
内连接返回两个表中满足连接条件的行。如果某行在一个表中没有匹配,则不会在结果集中出现。内连接是最常用的连接类型,因为它只返回那些在两个表中都有匹配项的行。
SQL 示例:
假设我们有两个表:employees
和 departments
。
employees
表:
employee_id | employee_name | department_id |
---|---|---|
1 | John Doe | 10 |
2 | Jane Smith | 20 |
3 | Bob Brown | 10 |
4 | Alice Johnson | NULL |
departments
表:
department_id | department_name |
---|---|
10 | Sales |
20 | Marketing |
30 | HR |
如果我们想要查询每个员工及其所在的部门,我们可以使用内连接:
sql复制代码
|---|----------------------------------------------------------------------------------|
| | SELECT employees.employee_name, departments.department_name
|
| | FROM employees
|
| | INNER JOIN departments ON employees.department_id = departments.department_id;
|
结果集:
employee_name | department_name |
---|---|
John Doe | Sales |
Jane Smith | Marketing |
Bob Brown | Sales |
注意:Alice Johnson 没有出现在结果集中,因为她在 employees
表中没有与 departments
表匹配的 department_id
。
2. 左连接(LEFT JOIN 或 LEFT OUTER JOIN)
左连接返回左表中的所有行,以及右表中满足连接条件的行。如果左表中的某行在右表中没有匹配项,则结果集中该行对应的右表部分将包含 NULL。左连接通常用于保留左表中的所有信息,即使右表中没有匹配项。
SQL 示例:
使用上面的 employees
和 departments
表,如果我们想要查询所有员工及其所在的部门(包括没有部门的员工),我们可以使用左连接:
sql复制代码
|---|---------------------------------------------------------------------------------|
| | SELECT employees.employee_name, departments.department_name
|
| | FROM employees
|
| | LEFT JOIN departments ON employees.department_id = departments.department_id;
|
结果集:
employee_name | department_name |
---|---|
John Doe | Sales |
Jane Smith | Marketing |
Bob Brown | Sales |
Alice Johnson | NULL |
注意:这次 Alice Johnson 出现在结果集中,但她的 department_name
是 NULL,因为她在 employees
表中没有与 departments
表匹配的 department_id
。
3. 右连接(RIGHT JOIN 或 RIGHT OUTER JOIN)
右连接与左连接相反。它返回右表中的所有行,以及左表中满足连接条件的行。如果右表中的某行在左表中没有匹配项,则结果集中该行对应的左表部分将包含 NULL。右连接在某些数据库系统中不常用,因为可以通过调整表的位置并使用左连接来达到相同的效果。然而,了解它的工作原理仍然很重要,以便在阅读或编写SQL代码时能够理解它。
SQL 示例:
使用上面的 employees
和 departments
表,如果我们想要查询所有部门及其员工(包括没有员工的部门),我们可以使用右连接:
sql复制代码
|---|----------------------------------------------------------------------------------|
| | SELECT employees.employee_name, departments.department_name
|
| | FROM employees
|
| | RIGHT JOIN departments ON employees.department_id = departments.department_id;
|
结果集:
employee_name | department_name |
---|---|
John Doe | Sales |
Bob Brown | Sales |
Jane Smith | Marketing |
NULL | HR |
注意:这次 HR 部门出现在结果集中,但它没有对应的员工名,因为 departments
表中的 HR 部门在 employees
表中没有匹配的 department_id
。另外,请注意这个查询可以通过将 employees
和 departments
表的位置互换并使用左连接来得到相同的结果。然而,在某些情况下,使用右连接可能会使查询更加清晰或符合特定的逻辑结构。