前言
在实际项目开发中,数据通常分散在多张表里。比如用户表、订单表、商品表、权限表,很少单表就能拿到完整结果。多表联查就是把多张表按关联条件合并,一次性查询出所需数据,是后端、测试、数据分析必备技能。
本文使用学生表 (student)、成绩表 (score)、课程表 (course) 三张经典案例表,从零讲解多表联查。
一、准备测试表与数据
先建表插数据,可直接复制运行:
-- 学生表
CREATE TABLE student(
id INT PRIMARY KEY,
name VARCHAR(20),
age INT,
gender VARCHAR(10)
);
-- 成绩表
CREATE TABLE score(
id INT PRIMARY KEY,
student_id INT,
course_id INT,
score INT
);
-- 课程表
CREATE TABLE course(
id INT PRIMARY KEY,
name VARCHAR(20)
);
-- 插入测试数据
INSERT INTO student VALUES(1,'张三',18,'男'),(2,'李四',19,'男'),(3,'翠花',18,'女');
INSERT INTO course VALUES(101,'语文'),(102,'数学'),(103,'英语');
INSERT INTO score VALUES(1,1,101,88),(2,1,102,95),(3,2,101,76),(4,3,103,92);
二、多表联查核心:连接类型一网打尽
1. INNER JOIN(内连接)
作用:只返回两张表匹配成功的数据,没有匹配的不显示。场景:查有成绩的学生 + 课程 + 分数。
SELECT
s.name AS 学生姓名,
c.name AS 课程名称,
sc.score AS 分数
FROM student s
INNER JOIN score sc ON s.id = sc.student_id
INNER JOIN course c ON sc.course_id = c.id;
要点:
- INNER JOIN 可以省略 INNER,直接写 JOIN
- ON 必须写关联条件,不能用错字段
- 结果只显示有成绩的学生
2. LEFT JOIN(左连接)
作用:左表数据全部显示,右表匹配不到显示 NULL。场景:查所有学生,不管有没有成绩。
SELECT
s.name AS 学生姓名,
c.name AS 课程名称,
sc.score AS 分数
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
LEFT JOIN course c ON sc.course_id = c.id;
使用最多:业务中常用左连接保证主表数据不丢失。
3. RIGHT JOIN(右连接)
作用:右表全部显示,左表匹配不到显示 NULL。场景:查所有课程,不管有没有人选。
SELECT
s.name AS 学生姓名,
c.name AS 课程名称,
sc.score AS 分数
FROM student s
RIGHT JOIN score sc ON s.id = sc.student_id
RIGHT JOIN course c ON sc.course_id = c.id;
4. FULL JOIN(全连接)
作用:左右表数据全部显示,匹配不上补 NULL。MySQL 不支持 FULL JOIN,可用 UNION 模拟:
-- 左连接 + 右连接 去重 = 全连接
SELECT * FROM student s LEFT JOIN score sc ON s.id=sc.student_id
UNION
SELECT * FROM student s RIGHT JOIN score sc ON s.id=sc.student_id;
三、多表联查高频用法
1. 三表联查(最常用)
学生 + 成绩 + 课程,一次性查出完整信息:
SELECT
s.id AS 学号,
s.name AS 姓名,
c.name AS 课程,
sc.score AS 成绩
FROM student s
JOIN score sc ON s.id=sc.student_id
JOIN course c ON sc.course_id=c.id;
2. 带条件的多表联查
查询张三的所有成绩:
SELECT
c.name AS 课程,
sc.score AS 分数
FROM student s
LEFT JOIN score sc ON s.id=sc.student_id
LEFT JOIN course c ON sc.course_id=c.id
WHERE s.name='张三';
3. 分组统计 + 多表联查
统计每个学生的平均分:
SELECT
s.name,
AVG(sc.score) AS 平均分
FROM student s
LEFT JOIN score sc ON s.id=sc.student_id
GROUP BY s.name;
4. 自连接(自己连自己)
适用:层级数据、上下级、评论回复等。
-- 示例:查询同龄学生
SELECT s1.name,s2.name
FROM student s1,student s2
WHERE s1.age=s2.age AND s1.id<>s2.id;
四、多表联查避坑指南(重点)
- 必须加 ON 条件,否则出现笛卡尔积(数据爆炸)
- 关联字段要加索引,大数据量联查必卡顿
- 少用 FULL JOIN,MySQL 不支持且效率低
- 别名简化表名(s=student、sc=score)可读性更高
- 先过滤再联查,用子查询 / WHERE 减少数据量
五、面试常问:JOIN 总结
- INNER JOIN:取交集
- LEFT JOIN:左表全量 + 右表匹配
- RIGHT JOIN:右表全量 + 左表匹配
- 多表联查:主表放左边,用 LEFT JOIN 最稳
六、总结
- 多表联查核心是找关联字段(外键)
- 日常开发优先用 LEFT JOIN
- 三表联查套路:主表 JOIN 附表 1 JOIN 附表 2
- 避坑:无 ON 必错、大数据必加索引
学会多表联查,你就能搞定 90% 的业务查询需求!
349

被折叠的 条评论
为什么被折叠?



