MySQL 七种JOIN连接详解

MySQL 七种JOIN连接详解

在数据库操作中,JOIN 是一个非常重要的概念,用于从多个表中检索数据。本文将详细介绍 MySQL 中的各种 JOIN 类型,并通过具体的例子进行说明。

表结构和假数据

为了更好地理解各种 JOIN 类型,我们首先创建两个简单的表并插入一些假数据。

employees 表

employee_id name department_id
1 张三 1
2 李四 2
3 王五 3
4 赵六 4

departments 表

department_id department_name
1 销售部
2 市场部
3 技术部
5 人力资源部

创建表和插入数据

sql 复制代码
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    name VARCHAR(50),
    department_id INT
);

CREATE TABLE departments (
    department_id INT PRIMARY KEY,
    department_name VARCHAR(50)
);

INSERT INTO employees (employee_id, name, department_id) VALUES
(1, '张三', 1),
(2, '李四', 2),
(3, '王五', 3),
(4, '赵六', 4);

INSERT INTO departments (department_id, department_name) VALUES
(1, '销售部'),
(2, '市场部'),
(3, '技术部'),
(5, '人力资源部');

1. 内连接(INNER JOIN)

内连接返回两个表中字段匹配关系的记录。只有当两个表中的记录满足连接条件时,这些记录才会出现在结果集中。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
INNER JOIN departments dept
ON emp.department_id = dept.department_id;

结果

name department_name
张三 销售部
李四 市场部
王五 技术部

2. 左外连接(LEFT JOIN 或 LEFT OUTER JOIN)

左外连接返回左表(employees 表)的所有记录,即使在右表(departments 表)中没有匹配的记录。如果右表中没有匹配的记录,那么结果集中的右表字段将填充 NULL。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
LEFT JOIN departments dept
ON emp.department_id = dept.department_id;

结果

name department_name
张三 销售部
李四 市场部
王五 技术部
赵六 NULL

3. 右外连接(RIGHT JOIN 或 RIGHT OUTER JOIN)

右外连接返回右表(departments 表)的所有记录,即使在左表(employees 表)中没有匹配的记录。如果左表中没有匹配的记录,那么结果集中的左表字段将填充 NULL。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
RIGHT JOIN departments dept
ON emp.department_id = dept.department_id;

结果

name department_name
张三 销售部
李四 市场部
王五 技术部
NULL 人力资源部

4. 全外连接(FULL JOIN 或 FULL OUTER JOIN)

MySQL 不直接支持全外连接,但可以通过 LEFT JOIN 和 RIGHT JOIN 的 UNION 来实现。全外连接返回两个表中的所有记录,如果某一边没有匹配的记录,则使用 NULL 填充。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
LEFT JOIN departments dept
ON emp.department_id = dept.department_id
UNION
SELECT emp.name, dept.department_name
FROM employees emp
RIGHT JOIN departments dept
ON emp.department_id = dept.department_id;

结果

name department_name
张三 销售部
李四 市场部
王五 技术部
赵六 NULL
NULL 人力资源部

5. 左连接加过滤(LEFT JOIN + WHERE)

这种情况下,我们使用左连接,但在 WHERE 子句中添加条件,以过滤出右表中没有匹配记录的行。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
LEFT JOIN departments dept
ON emp.department_id = dept.department_id
WHERE dept.department_name IS NULL;

结果

name department_name
赵六 NULL

6. 右连接加过滤(RIGHT JOIN + WHERE)

这种情况下,我们使用右连接,但在 WHERE 子句中添加条件,以过滤出左表中没有匹配记录的行。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
RIGHT JOIN departments dept
ON emp.department_id = dept.department_id
WHERE emp.name IS NULL;

结果

name department_name
NULL 人力资源部

7. 全外连接加过滤(FULL JOIN + WHERE)

这种情况下,我们使用全外连接,但在 WHERE 子句中添加条件,以过滤出两个表中都没有匹配记录的行。由于 MySQL 不直接支持 FULL JOIN,我们需要使用 LEFT JOIN 和 RIGHT JOIN 的 UNION 来实现。

SQL 示例

sql 复制代码
SELECT emp.name, dept.department_name
FROM employees emp
LEFT JOIN departments dept
ON emp.department_id = dept.department_id
WHERE dept.department_name IS NULL
UNION
SELECT emp.name, dept.department_name
FROM employees emp
RIGHT JOIN departments dept
ON emp.department_id = dept.department_id
WHERE emp.name IS NULL;

结果

name department_name
赵六 NULL
NULL 人力资源部

总结

通过这些示例,您可以更清楚地了解 MySQL 中各种 JOIN 操作的行为和结果。每种 JOIN 类型都有其特定的用途和应用场景,选择合适的 JOIN 类型可以有效地满足不同的查询需求。

相关推荐
时间的拾荒人6 小时前
Redis 主从复制详解:配置实操 + 原理机制
数据库·redis·面试
隔窗听雨眠6 小时前
MySQL三表JOIN执行内核与优化器决策机制
数据库·mysql·sql优化
Decay__7 小时前
SQLServer 索引与 SQL 优化 —— 聚集索引、非聚集索引、覆盖索引、碎片维护与执行计划
运维·数据库·sql·mysql·架构
笃行3508 小时前
【金仓数据库产品体验官】订单增量同步实战:MERGE、OUTPUT 与 IDENTITY 的兼容验证
数据库
星恒随风12 小时前
MySQL 从零入门(六):复合查询详解——多表查询、自连接、子查询与 UNION
linux·服务器·数据库·mysql
无奈笑天下13 小时前
银河麒麟上lsblk命令教程详解
linux·运维·服务器·数据库
xiaoye-duck14 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
AllData公司负责人15 小时前
AI大模型数据开发底座系列说明书:AllData集成DB-GPT开源项目建设 AI 多模态分析底座,涵盖模态解析/智能大屏/MCP 扩展!
大数据·数据库·人工智能·gpt·数据采集·数据接入·模态解析
隔窗听雨眠15 小时前
MySQL进程卡死的定位思路与恢复实践
mysql·故障排查·数据库运维
2601_9679873715 小时前
Sqlite参考手册
数据库·python·sqlite·api·教程