多表联查核心就是 join(连接) ,分为:inner join、left join、right join、full join(mysql 不支持,用 union 模拟),还有隐式连接(逗号写法)。
准备两张示例表
-- 用户表 user create table user( id int primary key auto_increment, name varchar(20), age int ); -- 订单表 order create table `order`( id int primary key auto_increment, user_id int, -- 外键,关联user.id order_name varchar(50) );
1、内连接 inner join(最常用)
只返回两张表匹配上的数据,两边都有才出结果 语法:
select 字段 from 表a inner join 表b on 表a.关联字段 = 表b.关联字段;
示例:查询用户以及对应的订单
select u.name, o.order_name from user u inner join `order` o on u.id = o.user_id;
别名:u 代表 user,o代表 order
隐式内连接(逗号写法,等价 inner join)
select u.name, o.order_name from user u,`order` o where u.id = o.user_id;
不要忘记 where 条件,否则会产生笛卡尔积(数据爆炸)
2、左连接 left join(left outer join)
以左边表为主,左表全部数据都展示;右表匹配不到,字段为 null
select u.name, o.order_name from user u left join `order` o on u.id = o.user_id;
场景:查询所有用户,包含没有下单的用户。
如果只想查左表有、右表没有的数据(没有订单的用户):
select u.name from user u left join `order` o on u.id = o.user_id where o.id is null;
3、右连接 right join
以右边表为主,右表全部数据,左表匹配不到则 null
select u.name, o.order_name from user u right join `order` o on u.id = o.user_id;
4、全连接 full join
mysql 没有 full join 关键字,想要左右全部数据,用 left join union right join
select u.name, o.order_name from user u left join `order` o on u.id=o.user_id union select u.name, o.order_name from user u right join `order` o on u.id=o.user_id;
5、三张及以上表联查
多张表就继续 join ... on 往后拼接
select u.name,o.order_name,g.goods_name from user u left join `order` o on u.id = o.user_id left join goods g on o.goods_id = g.id;
6、子查询实现多表(不是 join,另一种方案)
-- where中子查询 select * from user where id in (select user_id from `order`); -- from子查询(派生表) select * from (select * from user where age>18) t1 left join `order` o on t1.id = o.user_id;
7、关键注意事项
1.on 和 where 的区别
on:join 连接时做匹配条件where:连接完成之后,对结果集过滤
left join 中,条件写 on 和 where 结果完全不一样!
示例坑点:
-- ❌错误:left join后where过滤order表,会把null数据过滤掉,退化成内连接 select u.name,o.order_name from user u left join `order` o on u.id=o.user_id where o.order_name='手机'; -- ✅正确,把条件放on select u.name,o.order_name from user u left join `order` o on u.id=o.user_id and o.order_name='手机';
- 避免笛卡尔积:join 必须写 on 关联条件
- 字段重名,必须指定表别名:
u.id,不能只写id - 性能:关联字段建议建立索引(外键字段加索引,联查速度提升巨大)
快速选型记忆
| 连接类型 | 作用 |
|---|---|
| inner join | 两边匹配的数据 |
| left join | 左边全部,右边匹配 |
| right join | 右边全部,左边匹配 |
| union | 合并结果集 |
到此这篇关于mysql中多表联查join的常见用法详解的文章就介绍到这了,更多相关mysql多表联查内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论