在mysql的多表查询场景中,INNER JOIN和LEFT JOIN是两种核心的连接方式,两者的核心差异在于对匹配失败数据的处理逻辑不同,最终返回的查询结果集也存在明显区别。

基础定义与语法
INNER JOIN
INNER JOIN即内连接,它的作用是返回两个表中满足连接条件的交集数据。只有当左表和右表的连接字段匹配时,对应的行才会被保留到结果集中,任何一侧表中没有匹配到的数据都会被直接过滤掉。
基础语法如下:
-- INNER JOIN 语法,INNER关键字可以省略 SELECT 字段列表 FROM 左表 INNER JOIN 右表 ON 左表.连接字段 = 右表.连接字段;
LEFT JOIN
LEFT JOIN即左连接,它会返回左表的所有数据,即使右表中没有匹配到对应的连接字段值。如果右表没有匹配的数据,那么结果集中右表对应的字段会显示为NULL。
基础语法如下:
-- LEFT JOIN 语法,LEFT OUTER JOIN 等价于 LEFT JOIN,OUTER可省略 SELECT 字段列表 FROM 左表 LEFT JOIN 右表 ON 左表.连接字段 = 右表.连接字段;
示例数据准备
为了更直观地展示两者的区别,我们先创建两张测试表并插入测试数据。第一张是学生表student,存储学生基本信息;第二张是成绩表score,存储学生的考试成绩,部分学生可能没有成绩记录。
-- 创建学生表
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT
);
-- 创建成绩表
CREATE TABLE score (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT,
subject VARCHAR(50),
grade INT
);
-- 插入学生数据
INSERT INTO student (name, age) VALUES
('张三', 18),
('李四', 19),
('王五', 20),
('赵六', 18);
-- 插入成绩数据,赵六没有成绩记录
INSERT INTO score (student_id, subject, grade) VALUES
(1, '数学', 90),
(1, '语文', 85),
(2, '数学', 88),
(3, '英语', 92);
查询结果对比
INNER JOIN查询结果
使用INNER JOIN连接学生表和成绩表,连接条件为学生表的id等于成绩表的student_id:
SELECT
s.id AS student_id,
s.name,
s.age,
sc.subject,
sc.grade
FROM student s
INNER JOIN score sc
ON s.id = sc.student_id;
查询结果如下:
| student_id | name | age | subject | grade |
|---|---|---|---|---|
| 1 | 张三 | 18 | 数学 | 90 |
| 1 | 张三 | 18 | 语文 | 85 |
| 2 | 李四 | 19 | 数学 | 88 |
| 3 | 王五 | 20 | 英语 | 92 |
可以看到,学生赵六在成绩表中没有对应的记录,因此没有被查询出来,结果集只包含有匹配成绩的学生数据。
LEFT JOIN查询结果
使用LEFT JOIN连接两张表,保持相同的连接条件:
SELECT
s.id AS student_id,
s.name,
s.age,
sc.subject,
sc.grade
FROM student s
LEFT JOIN score sc
ON s.id = sc.student_id;
查询结果如下:
| student_id | name | age | subject | grade |
|---|---|---|---|---|
| 1 | 张三 | 18 | 数学 | 90 |
| 1 | 张三 | 18 | 语文 | 85 |
| 2 | 李四 | 19 | 数学 | 88 |
| 3 | 王五 | 20 | 英语 | 92 |
| 4 | 赵六 | 18 | NULL | NULL |
此时左表的所有学生数据都被保留,赵六虽然没有成绩记录,但仍然出现在结果集中,对应的科目和成绩字段显示为NULL。
核心差异总结
- 返回数据范围不同:INNER JOIN只返回两表匹配的交集数据,LEFT JOIN返回左表全部数据,右表匹配不到则补NULL。
- 匹配失败数据处理不同:INNER JOIN直接过滤无匹配的数据,LEFT JOIN保留左表无匹配的数据。
- 适用场景不同:如果需要查询两表都有关联的数据,使用INNER JOIN;如果需要查询左表全部数据,即使右表没有关联数据也要展示,使用LEFT JOIN。
常见使用误区
很多开发者会在LEFT JOIN的WHERE子句中过滤右表字段,这会导致LEFT JOIN的效果失效,变成和INNER JOIN一样的结果。例如下面的查询:
-- 错误示例,WHERE过滤右表字段会让LEFT JOIN失效
SELECT
s.id AS student_id,
s.name,
s.age,
sc.subject,
sc.grade
FROM student s
LEFT JOIN score sc
ON s.id = sc.student_id
WHERE sc.grade > 90;
这个查询会把赵六以及成绩小于等于90的记录都过滤掉,因为sc.grade为NULL时不符合大于90的条件。如果需要在LEFT JOIN中过滤右表数据,应该把过滤条件放在ON子句中:
-- 正确示例,过滤条件放在ON子句中
SELECT
s.id AS student_id,
s.name,
s.age,
sc.subject,
sc.grade
FROM student s
LEFT JOIN score sc
ON s.id = sc.student_id AND sc.grade > 90;
这样查询会保留所有学生,只有成绩大于90的才会显示对应的成绩信息,赵六仍然会保留在结果集中。
mysqlINNER_JOINLEFT_JOINsql_join修改时间:2026-06-17 21:45:44