在MySQL的多表查询场景中,left join、right join和inner join是三种最基础的连接方式,它们的核心作用都是将多张表的数据按照关联条件拼接起来,但返回的结果范围存在明显差异。理解三者的用法和区别,是写出正确多表查询语句的基础。

三种join的基础语法
三种join的基础语法结构类似,都需要指定关联的两张表以及关联条件,具体语法如下:
-- inner join 语法 SELECT 字段列表 FROM 表1 INNER JOIN 表2 ON 表1.关联字段 = 表2.关联字段; -- left join 语法 SELECT 字段列表 FROM 表1 LEFT JOIN 表2 ON 表1.关联字段 = 表2.关联字段; -- right join 语法 SELECT 字段列表 FROM 表1 RIGHT JOIN 表2 ON 表1.关联字段 = 表2.关联字段;
准备测试数据
为了更直观地展示三种join的返回结果,我们先创建两张测试表,分别插入测试数据:
-- 创建用户表
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20)
);
-- 创建订单表
CREATE TABLE order_info (
order_id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2)
);
-- 插入用户表数据
INSERT INTO user VALUES (1, '张三'), (2, '李四'), (3, '王五');
-- 插入订单表数据
INSERT INTO order_info VALUES (101, 1, 199.99), (102, 1, 299.99), (103, 2, 99.99);
此时user表有3条用户数据,order_info表有3条订单数据,其中用户id为3的王五没有对应的订单记录,订单表的user_id都对应user表中存在的用户。
inner join的用法与结果
inner join也叫内连接,它的返回结果是同时满足两张表关联条件的记录,也就是两张表的交集部分。如果某条记录在左表存在但在右表没有匹配的关联记录,或者右表存在左表没有匹配的关联记录,都不会出现在返回结果中。
我们使用inner join查询用户和对应的订单信息:
SELECT u.id, u.name, o.order_id, o.amount FROM user u INNER JOIN order_info o ON u.id = o.user_id;
返回结果如下:
| id | name | order_id | amount |
|---|---|---|---|
| 1 | 张三 | 101 | 199.99 |
| 1 | 张三 | 102 | 299.99 |
| 2 | 李四 | 103 | 99.99 |
可以看到,用户王五因为没有对应的订单记录,所以没有出现在结果中,订单表中也不存在没有对应用户的订单,所以所有订单都正常返回。
left join的用法与结果
left join也叫左连接,它的返回结果是左表的所有记录,加上右表中满足关联条件的记录。如果左表的某条记录在右表没有匹配的关联记录,那么右表对应的字段会显示为NULL。
我们使用left join查询所有用户以及对应的订单信息:
SELECT u.id, u.name, o.order_id, o.amount FROM user u LEFT JOIN order_info o ON u.id = o.user_id;
返回结果如下:
| id | name | order_id | amount |
|---|---|---|---|
| 1 | 张三 | 101 | 199.99 |
| 1 | 张三 | 102 | 299.99 |
| 2 | 李四 | 103 | 99.99 |
| 3 | 王五 | NULL | NULL |
可以看到,左表user的所有3条记录都返回了,王五没有对应的订单,所以订单相关字段显示为NULL。如果有用户在订单表有多个订单,也会正常返回多条记录。
right join的用法与结果
right join也叫右连接,它的返回结果是右表的所有记录,加上左表中满足关联条件的记录。如果右表的某条记录在左表没有匹配的关联记录,那么左表对应的字段会显示为NULL。右连接的逻辑和左连接完全相反,只是主导表变成了右表。
我们使用right join查询所有订单以及对应的用户信息:
SELECT u.id, u.name, o.order_id, o.amount FROM user u RIGHT JOIN order_info o ON u.id = o.user_id;
返回结果如下:
| id | name | order_id | amount |
|---|---|---|---|
| 1 | 张三 | 101 | 199.99 |
| 1 | 张三 | 102 | 299.99 |
| 2 | 李四 | 103 | 99.99 |
当前测试数据中订单表的user_id都对应user表中存在的用户,所以结果和inner join一致。如果订单表存在一条没有对应用户的订单记录,比如插入INSERT INTO order_info VALUES (104, 4, 399.99);,再执行上面的right join查询,就会返回4条记录,其中id和name字段为NULL,对应user_id为4的订单。
三者的核心区别对比
我们可以通过下表快速对比三种join的核心差异:
| 连接类型 | 返回结果范围 | 无匹配记录时的处理 |
|---|---|---|
| inner join | 两表关联条件的交集 | 无匹配则不返回该记录 |
| left join | 左表全部记录 + 右表匹配记录 | 右表字段显示为NULL |
| right join | 右表全部记录 + 左表匹配记录 | 左表字段显示为NULL |
使用场景建议
- 如果需要查询两张表都满足关联条件的数据,比如查询有订单的用户和订单信息,使用inner join。
- 如果需要查询左表的全部数据,同时关联右表的匹配数据,比如查询所有用户以及他们的订单,不管用户有没有下单,使用left join。
- 如果需要查询右表的全部数据,同时关联左表的匹配数据,比如查询所有订单以及对应的用户,不管订单有没有对应用户,使用right join。实际开发中left join的使用频率远高于right join,因为可以通过调整表的顺序用left join替代right join。
注意事项
使用join时需要注意关联条件的写法,如果忘记写ON后面的关联条件,会产生笛卡尔积,也就是左表每条记录和右表每条记录都组合一次,数据量会急剧膨胀,严重影响查询性能。另外,关联字段最好建立索引,能大幅提升join查询的效率。
如果需要过滤右表的记录,过滤条件要写在ON后面,而不是WHERE后面。比如要查询所有用户以及他们的金额大于200的订单,正确的写法是:
SELECT u.id, u.name, o.order_id, o.amount FROM user u LEFT JOIN order_info o ON u.id = o.user_id AND o.amount > 200;
如果把o.amount > 200写在WHERE后面,就会把王五这条没有订单的记录过滤掉,变成inner join的效果,因为NULL不满足大于200的条件。
MySQLleft_joinright_joininner_join修改时间:2026-06-24 12:51:22