mysql5.7 原生支持 inner、left、right、cross、self 五种标准 join;不支持直接写 full outer join,需用 left + right + union 模拟;另外衍生出左独有、右独有、两表独有三种筛选写法,行业常统称 7 种 join 逻辑。
基础前置测试表
-- 用户表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。
语法
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 可省略。
语法
select * from t_user u left join t_order o on u.uid = o.uid;
结果
张三、李四带订单数据,王五无订单,订单字段全为 null。
right [outer] join 右外连接
右表全量 + 匹配左表
作用
保留右表所有行,左表无匹配填充 null;mysql 底层会自动转 left join 执行。
语法
select * from t_user u right join t_order o on u.uid = o.uid;
结果
101、102 订单匹配用户,103 订单无用户,用户字段全 null。
cross join 交叉连接
笛卡尔积
作用
无关联条件,左表每一行匹配右表每一行,数据量 = 左行数 × 右行数,慎用大表。
两种等价写法:
-- 写法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 相同模拟关联
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 模拟。
模拟语法
-- 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
select * from t_user u left join t_order o on u.uid=o.uid where o.oid is null; -- 只查出王五(无订单用户)
右独有(只存在右表,左表无匹配)
右 join 过滤左表主键 is null
select * from t_user u right join t_order o on u.uid=o.uid where u.uid is null; -- 只查出103订单(无归属用户)
两表独有(全连接去掉交集,只保留两边独有数据)
-- 左独有 (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 模拟,并衍生左独有、右独有、两表独有三种筛选写法,附语法、结果与速查表,便于业务选型。
以上就是一文详解mysql 5.7的七种join连接方式的详细内容,更多关于mysql 5.7 join连接方式的资料请关注代码网其它相关文章!
发表评论