MySQL5.7 原生支持 INNER、LEFT、RIGHT、CROSS、SELF 五种标准 JOIN;不支持直接写 FULL OUTER JOIN ,需用
LEFT + RIGHT + UNION模拟;另外衍生出左独有、右独有、两表独有三种筛选写法,行业常统称 7 种 JOIN 逻辑。
目录
[INNER JOIN 内连接](#INNER JOIN 内连接)
[LEFT OUTER JOIN 左外连接](#LEFT [OUTER] JOIN 左外连接)
[RIGHT OUTER JOIN 右外连接](#RIGHT [OUTER] JOIN 右外连接)
[CROSS JOIN 交叉连接](#CROSS JOIN 交叉连接)
[SELF JOIN 自连接](#SELF JOIN 自连接)
[FULL OUTER JOIN 全外连接](#FULL OUTER JOIN 全外连接)
[衍生 3 种筛选 JOIN(业务高频使用)](#衍生 3 种筛选 JOIN(业务高频使用))
[各 JOIN 对比速查表](#各 JOIN 对比速查表)

基础前置测试表
sql
-- 用户表A
CREATE TABLE t_user(uid INT, uname VARCHAR(20));
INSERT t_user VALUES(1,'张三'),(2,'李四'),(3,'王五');
-- 订单表B
CREATE TABLE t_order(oid INT, uid INT, money DECIMAL);
INSERT t_order VALUES(101,1,99),(102,2,199),(103,4,299);
INNER JOIN 内连接
Intersection
作用
只返回两表匹配成功 的数据,无匹配直接过滤;简写 JOIN 等价 INNER JOIN。
语法
sql
SELECT * FROM t_user u
INNER JOIN t_order o ON u.uid = o.uid;
-- 简写:JOIN
SELECT * FROM t_user u JOIN t_order o ON u.uid = o.uid;
结果
只保留 uid=1、2(张三、李四有订单),王五、订单 4 全部过滤。
LEFT OUTER JOIN 左外连接
左表全量 + 匹配右表
作用
保留左表所有行 ,右表无匹配则填充 NULL;OUTER 可省略。
语法
sql
SELECT * FROM t_user u
LEFT JOIN t_order o ON u.uid = o.uid;
结果
张三、李四带订单数据,王五无订单,订单字段全为 NULL。
RIGHT OUTER JOIN 右外连接
右表全量 + 匹配左表
作用
保留右表所有行 ,左表无匹配填充 NULL;MySQL 底层会自动转 LEFT JOIN 执行。
语法
sql
SELECT * FROM t_user u
RIGHT JOIN t_order o ON u.uid = o.uid;
结果
101、102 订单匹配用户,103 订单无用户,用户字段全 NULL。
CROSS JOIN 交叉连接
笛卡尔积
作用
无关联条件,左表每一行匹配右表每一行,数据量 = 左行数 × 右行数,慎用大表。
两种等价写法:
sql
-- 写法1 CROSS JOIN
SELECT * FROM t_user CROSS JOIN t_order;
-- 写法2 逗号分隔(无WHERE关联)
SELECT * FROM t_user, t_order;
示例 3 用户 ×3 订单 = 9 条全部组合数据。
SELF JOIN 自连接
同表自己关联自己
作用
一张表自己和自己 JOIN,必须起别名;适用于层级、上下级、同表对比场景。
示例:
查询同表用户 id 相同模拟关联
sql
SELECT a.uid,a.uname,b.uname
FROM t_user a
LEFT JOIN t_user b ON a.uid = b.uid;
经典场景:员工表查上级、分类表查父级分类。
FULL OUTER JOIN 全外连接
(MySQL5.7 无原生语法,模拟实现)
作用
返回左右两表全部数据 ,无匹配填充 NULL;MySQL 不支持直接 FULL OUTER JOIN,用 LEFT UNION RIGHT 模拟。
模拟语法
sql
-- UNION自动去重(推荐)
(SELECT * FROM t_user u LEFT JOIN t_order o ON u.uid=o.uid)
UNION
(SELECT * FROM t_user u RIGHT JOIN t_order o ON u.uid=o.uid);
UNION:自动合并重复匹配行UNION ALL:不去重,性能更高,匹配数据会重复两份
结果
张三、李四、王五、订单 4 全部出现,无匹配字段 NULL。
衍生 3 种筛选 JOIN(业务高频使用)
左独有(只存在左表,右表无匹配)
左 JOIN 后过滤右表主键 IS NULL
sql
SELECT * FROM t_user u
LEFT JOIN t_order o ON u.uid=o.uid
WHERE o.oid IS NULL; -- 只查出王五(无订单用户)
右独有(只存在右表,左表无匹配)
右 JOIN 过滤左表主键 IS NULL
sql
SELECT * FROM t_user u
RIGHT JOIN t_order o ON u.uid=o.uid
WHERE u.uid IS NULL; -- 只查出103订单(无归属用户)
两表独有(全连接去掉交集,只保留两边独有数据)
sql
-- 左独有
(SELECT * FROM t_user u LEFT JOIN t_order o ON u.uid=o.uid WHERE o.oid IS NULL)
UNION
-- 右独有
(SELECT * FROM t_user u RIGHT JOIN t_order o ON u.uid=o.uid WHERE u.uid IS NULL);
各 JOIN 对比速查表
| 连接类型 | 保留数据范围 | MySQL 原生支持 | 常用场景 |
|---|---|---|---|
| INNER JOIN | 两表交集 | ✅ | 查询两表都存在的关联数据(用户 + 有效订单) |
| LEFT JOIN | 左表全部 + 匹配右表 | ✅ | 查全部用户,不管有没有下单 |
| RIGHT JOIN | 右表全部 + 匹配左表 | ✅ | 查全部订单,不管是否绑定用户 |
| CROSS JOIN | 笛卡尔积全组合 | ✅ | 生成排列组合、测试数据 |
| SELF JOIN | 同表自关联 | ✅ | 树形结构、上下级查询 |
| FULL JOIN | 左右两表全部 | ❌ UNION 模拟 | 完整合并两张表所有数据 |
| 左独有 / 右独有 / 两表独有 | 单边无匹配数据 | 派生写法 | 查缺失关联数据(未下单用户、孤儿订单) |
总结
本文系统梳理 MySQL 5.7 的 7 种 JOIN 逻辑:INNER、LEFT、RIGHT、CROSS、SELF 五种原生连接,FULL OUTER JOIN 用 LEFT UNION RIGHT 模拟,并衍生左独有、右独有、两表独有三种筛选写法,附语法、结果与速查表,便于业务选型。