如何实现MySQL多表联查

MySQL 多表联查

多表联查核心就是 JOIN(连接) ,分为:INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN(MySQL 不支持,用 union 模拟),还有隐式连接(逗号写法)。

准备两张示例表

sql 复制代码
-- 用户表 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(最常用)

只返回两张表匹配上的数据,两边都有才出结果 语法:

css 复制代码
SELECT 字段
FROM 表A
INNER JOIN 表B
ON 表A.关联字段 = 表B.关联字段;

示例:查询用户以及对应的订单

sql 复制代码
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)

sql 复制代码
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

sql 复制代码
SELECT u.name, o.order_name
FROM user u
LEFT JOIN `order` o
ON u.id = o.user_id;

场景:查询所有用户,包含没有下单的用户。

如果只想查左表有、右表没有的数据(没有订单的用户):

sql 复制代码
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

sql 复制代码
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

sql 复制代码
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 往后拼接

sql 复制代码
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,另一种方案)

sql 复制代码
-- 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 结果完全不一样!

示例坑点:

sql 复制代码
-- ❌错误: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='手机';
  1. 避免笛卡尔积:join 必须写 on 关联条件
  2. 字段重名,必须指定表别名:u.id,不能只写id
  3. 性能:关联字段建议建立索引(外键字段加索引,联查速度提升巨大)

快速选型记忆

表格

连接类型 作用
INNER JOIN 两边匹配的数据
LEFT JOIN 左边全部,右边匹配
RIGHT JOIN 右边全部,左边匹配
UNION 合并结果集
相关推荐
Csvn8 小时前
WASM
前端
修己xj9 小时前
我用 AI 给自己写了一个 Markdown 编辑器,然后把它开源了
前端
FRing039 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿10 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
moshuying11 小时前
网购能买Token了!
前端
h_654321011 小时前
echarts实现柱状图加一条横线
前端·echarts
风骏时光牛马12 小时前
生成一个后端标题,只需要一个标题,不需要其他的任何文本。
前端
子非鱼@Itfuture12 小时前
关于前后端联调中登录状态/登录信息失效?
java·前端
郭小李12 小时前
openFeign入门
java·开发语言·前端
馒头不想说话12 小时前
AI当运营,帮你省人力
前端