在 MySQL 中,INNER JOIN
、LEFT JOIN
和 RIGHT JOIN
是常用的表连接方式,它们的核心区别在于如何处理 匹配和未匹配的记录。以下是详细对比:
1. INNER JOIN(内连接)
定义
- 仅返回两个表中满足连接条件的匹配行。如果左表或右表中没有匹配的记录,则这些行被忽略。
- 特点:结果集是两个表的交集。
语法
SELECT columns
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
示例
假设表A(学生表)和表B(成绩表):
-- 表A: 学生信息
+----+--------+
| ID | Name |
+----+--------+
| 1 | Bob |
| 2 | Sue |
| 3 | Tom |
+----+--------+
-- 表B: 成绩信息
+----+--------+-------+
| ID | City | Score |
+----+--------+-------+
| 1 | New York| 90 |
| 3 | Boston | 85 |
| 4 | Chicago | 95 |
+----+--------+-------+
执行 INNER JOIN
:
SELECT A.ID, A.Name, B.City, B.Score
FROM A
INNER JOIN B ON A.ID = B.ID;
结果:
+----+--------+--------+-------+
| ID | Name | City | Score |
+----+--------+--------+-------+
| 1 | Bob | New York| 90 |
| 3 | Tom | Boston | 85 |
+----+--------+--------+-------+
- 仅返回匹配的行(ID=1和ID=3)。
使用场景
- 需要严格匹配两个表的记录(如查询有成绩的学生)。
- 性能优势:通常比
LEFT JOIN
和RIGHT JOIN
更快,因为它只处理匹配的行。
2. LEFT JOIN(左连接)
定义
- 返回左表的所有行,以及右表中匹配的行。如果右表中没有匹配的记录,则右表字段为
NULL
。 - 特点:结果集是左表的全集 + 右表的匹配部分(右表不足部分用
NULL
填充)。
语法
SELECT columns
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;
示例
执行 LEFT JOIN
:
SELECT A.ID, A.Name, B.City, B.Score
FROM A
LEFT JOIN B ON A.ID = B.ID;
结果:
+----+--------+--------+-------+
| ID | Name | City | Score |
+----+--------+--------+-------+
| 1 | Bob | New York| 90 |
| 2 | Sue | NULL | NULL |
| 3 | Tom | Boston | 85 |
+----+--------+--------+-------+
- 保留左表所有行(ID=2 的
Sue
无成绩,右表字段为NULL
)。
使用场景
- 需要保留左表所有记录,即使右表没有匹配(如查询所有学生及其成绩,包括无成绩的学生)。
- 注意:在
LEFT JOIN
后使用WHERE
条件时,需注意左表字段的过滤逻辑(避免误过滤左表记录)。
3. RIGHT JOIN(右连接)
定义
- 返回右表的所有行,以及左表中匹配的行。如果左表中没有匹配的记录,则左表字段为
NULL
。 - 特点:结果集是右表的全集 + 左表的匹配部分(左表不足部分用
NULL
填充)。
语法
SELECT columns
FROM table1
RIGHT JOIN table2
ON table1.column = table2.column;
示例
执行 RIGHT JOIN
:
SELECT A.ID, A.Name, B.City, B.Score
FROM A
RIGHT JOIN B ON A.ID = B.ID;
结果:
+----+--------+--------+-------+
| ID | Name | City | Score |
+----+--------+--------+-------+
| 1 | Bob | New York| 90 |
| 3 | Tom | Boston | 85 |
| 4 | NULL | Chicago | 95 |
+----+--------+--------+-------+
- 保留右表所有行(ID=4 的
Chicago
无对应学生,左表字段为NULL
)。
使用场景
- 需要保留右表所有记录,即使左表没有匹配(如查询所有成绩及其对应学生,包括无学生的成绩)。
4. 核心对比表
特性 | INNER JOIN | LEFT JOIN | RIGHT JOIN |
---|---|---|---|
返回匹配的行 | 是 | 是 | 是 |
返回左表无匹配行 | 否 | 是 | 否 |
返回右表无匹配行 | 否 | 否 | 是 |
性能 | 通常最快 | 次之 | 次之 |
典型使用场景 | 严格匹配数据 | 保留左表全部数据 | 保留右表全部数据 |
5. 注意事项
- 性能优化:
INNER JOIN
通常比LEFT JOIN
和RIGHT JOIN
更快,因为它只处理匹配的行。- 确保连接字段有索引,避免全表扫描。
- ON 与 WHERE 的区别:
LEFT JOIN
中,ON
条件影响连接逻辑,WHERE
条件会过滤结果集(可能排除左表无匹配的行)。
- MySQL 不支持
FULL JOIN
:- 如果需要类似功能,可通过
UNION
结合LEFT JOIN
和RIGHT JOIN
实现。
- 如果需要类似功能,可通过
THE END