MySQL系列-join的用法
导言
在数据库操作中,JOIN是实现多表关联查询的核心机制。相较于嵌套子查询和IN操作符,合理使用JOIN能显著提升查询性能,优化执行计划,并增强SQL代码的可读性与可维护性。本文将系统解析MySQL中的JOIN语法类型,涵盖INNER JOIN、LEFT JOIN、RIGHT JOIN等核心关联方式,并通过典型业务场景示例,演示如何通过表连接构建高效的数据检索逻辑。
表结构和数据
为了更好地理解各种 JOIN 类型,我们首先创建两个简单的表并插入一些假数据。
表结构
CREATE TABLE employees ( employeeid INT PRIMARY KEY, name VARCHAR(50), departmentid INT ); CREATE TABLE departments ( departmentid INT PRIMARY KEY, departmentname VARCHAR(50) );
插入数据
INSERT INTO employees (employeeid, name, departmentid) VALUES (1, '张三', 1), (2, '李四', 2), (3, '王五', 3), (4, '赵六', 4); INSERT INTO departments (departmentid, departmentname) VALUES (1, '销售部'), (2, '市场部'), (3, '技术部'), (5, '人力资源部');
实操展示
1. 内连接(INNER JOIN)
概念
INNER JOIN基于等值关联条件返回两个表的匹配记录,仅保留满足关联条件的行对组合。其执行逻辑是先生成两表笛卡尔积,再通过ON子句指定的关联条件过滤出有效匹配数据。
示例
SELECT employees.name, departments.departmentname FROM employees INNER JOIN departments ON employees.departmentid = departments.departmentid;
输出结果
| name | departmentname |
|---|---|
| 张三 | 销售部 |
| 李四 | 市场部 |
| 王五 | 技术部 |
2. 左连接(LEFT JOIN)
概念
LEFT JOIN(左外连接)保留左表(驱动表)即FROM表所有记录的完整集合,即使右表(关联表)不存在匹配行。当右表无对应记录时,结果集将补全右表字段的NULL值。其执行逻辑为:先根据关联条件匹配左右表数据,再强制保留左表全量记录,未匹配的右表字段以NULL填充。
示例
SELECT employees.name, departments.departmentname FROM employees LEFT JOIN departments ON employees.departmentid = departments.departmentid;
输出结果
| name | departmentname |
|---|---|
| 张三 | 销售部 |
| 李四 | 市场部 |
| 王五 | 技术部 |
| 赵六 | NULL |
3. 右连接(RIGHT JOIN)
概念
RIGHT JOIN(右外连接)保留右表(驱动表)即JOIN表的所有记录,即使左表(关联表)不存在匹配行。当左表无对应记录时,结果集将补全左表字段的NULL值。其执行逻辑为:先通过关联条件匹配数据,再强制保留右表全量记录,未匹配的左表字段以NULL填充,与LEFT JOIN形成对称的外连接操作。
示例
SELECT employees.name, departments.departmentname FROM employees RIGHT JOIN departments ON employees.departmentid = departments.departmentid;
输出结果
| name | departmentname |
|---|---|
| 张三 | 销售部 |
| 李四 | 市场部 |
| 王五 | 技术部 |
| NULL | 人力资源部 |
4. 全连接(FULL JOIN)
概念
MySQL中FULL JOIN(全连接)的语义是返回左表和右表所有基表记录的并集。当某行在任一关联表中无匹配项时,结果集对应缺失列将补全NULL值。但需注意:MySQL原生不支持FULL JOIN语法,通常通过UNION联合LEFT JOIN与RIGHT 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;
输出结果
| name | departmentname |
|---|---|
| 张三 | 销售部 |
| 李四 | 市场部 |
| 王五 | 技术部 |
| 赵六 | NULL |
| NULL | 人力资源部 |
总结
一句话总结:内连接保留双方都有的记录;左连接保留FROM表的记录,找不到则填充NULL;右连接保留JOIN表的记录找不到则填充NULL;全连接是保留双方的记录,找不到填充NULL

