如何实现MySQL多表联查

MySQL 多表联查

多表联查核心就是 JOIN(连接) ,分为:INNER JOINLEFT JOINRIGHT JOINFULL 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 合并结果集
相关推荐
今天AI了吗1 小时前
【AI】一文讲清 RAG:从大模型局限到企业级知识库落地流程
前端·javascript·人工智能·python·深度学习·机器学习·easyui
hunterandroid1 小时前
[鸿蒙从零到一] HarmonyOS 冷启动瀑布图分析与关键路径裁剪实战
前端·华为
郭邯1 小时前
用 Canvas 实现纯前端图片格式互转:PNG/JPG/WebP 一键切换,还能控制质量与尺寸
前端
工边页字1 小时前
Electron应用的8种防护方式
前端·javascript·electron
labixiong1 小时前
z-index: 99999 输给 z-index: 2?原生弹窗的 Top Layer 排位战:后进者居上、看得见却点不着
前端·html
deli0071 小时前
CSS 渐变生成器:拖两个颜色直接给代码,做按钮背景不用手写
前端
芳心粽伙饭2 小时前
HTML第八章 表单标签
前端·html
Darling噜啦啦2 小时前
从 SSE 到 LLM 流式输出:搞懂前端实时通信的两种姿势
前端·后端·llm