🤔 为什么查询数据要"连表"?一张图说清多表查询的底层逻辑!
大家好呀!我是数据库小学妹👋一个正在从设计转行学数据库的"萌新"。
昨天学完主键、外键和约束后,我就在想一个问题:
"我有学生表,也有成绩表,怎么一次性查出'每个学生的姓名和成绩'?"
但现实中的数据往往分散在多个表里! 这时候,就需要用到多表关联查询了!
今天这篇,我就用最直白的话,把INNER JOIN、LEFT JOIN、RIGHT JOIN讲清楚!
保证你一看就懂!
一、为什么需要多表关联查询?
先看个实际场景:
学生表(students)
| id | name | age |
|---|---|---|
| 1 | 张三 | 18 |
| 2 | 李四 | 19 |
| 3 | 王五 | 20 |
成绩表(scores)
| id | student_id | subject | score |
|---|---|---|---|
| 1 | 1 | 数学 | 90 |
| 2 | 1 | 英语 | 85 |
| 3 | 2 | 数学 | 78 |
需求:查出每个学生的姓名和数学成绩
❌ 错误做法:分别查两个表,然后手动匹配
✅ 正确做法:用JOIN把两个表"连"起来!
💡 核心逻辑:通过外键关联,把分散在不同表的数据"拼"在一起!
二、INNER JOIN:只查"都有"的数据
INNER JOIN = 内连接 = 只返回两个表都有的数据
✨ 适用场景:
- 查"既有学生信息又有成绩记录"的数据
- 查"既有订单又有用户"的数据
🛠️ 语法:
SELECT students.name, scores.score
FROM students
INNER JOIN scores ON students.id = scores.student_id;
📊 效果:

结果:只返回张三和李四(王五没成绩,不显示)
💡 我的理解:
INNER JOIN就像交集——只保留两个表都有的部分!
三、LEFT JOIN:以左表为主,查"左边所有"
LEFT JOIN = 左连接 = 返回左表所有数据 + 右表匹配的数据
✨ 适用场景:
- 查"所有学生",包括没有成绩的
- 查"所有用户",包括没有订单的
🛠️ 语法:
SELECT students.name, scores.score
FROM students
LEFT JOIN scores ON students.id = scores.student_id;
📊 效果图:

结果:张三、李四、王五都显示(王五成绩为NULL)
💡 我的理解:
LEFT JOIN就像左表的全部 + 右表的匹配部分!
"左"字诀:左边的都要,右边的有就拿,没有就NULL!
四、RIGHT JOIN:以右表为主,查"右边所有"
RIGHT JOIN = 右连接 = 返回右表所有数据 + 左表匹配的数据
✨ 适用场景:
- 查"所有成绩",包括没有学生信息的(数据异常时用)
- 查"所有订单",包括没有用户信息的
🛠️ 语法:
SELECT students.name, scores.score
FROM students
RIGHT JOIN scores ON students.id = scores.student_id;
📊 效果图:

结果:所有成绩都显示(如果成绩表有学生表没有的数据,也会显示)
💡 我的理解:
RIGHT JOIN和LEFT JOIN相反,"右"字诀:右边的都要,左边的有就拿,没有就NULL!
五、一张图说清三种JOIN的区别

六、实战案例:学生管理系统查询
案例1:查所有学生的数学成绩(包括没成绩的)
SELECT students.name, scores.score
FROM students
LEFT JOIN scores
ON students.id = scores.student_id
AND scores.subject = '数学';
案例2:查有成绩记录的学生
SELECT students.name, scores.score
FROM students
INNER JOIN scores ON students.id = scores.student_id;
案例3:查所有成绩记录(包括异常数据)
SELECT students.name, scores.score
FROM students
RIGHT JOIN scores ON students.id = scores.student_id;
七、常见误区
| 常见错误 | 正确做法 |
|---|---|
| 忘记写 ON 条件 | 会产生笛卡尔积(A表每行 × B表每行),数据爆炸 |
ON 条件写错(比如 s.id = sc.id) |
仔细检查关联字段是不是外键关系 |
| 列名重复不指定表名 | 用 表名.列名 或别名区分 |
| 用 INNER JOIN 查不到没有匹配的数据 | 如果想查所有学生(即使没成绩),用 LEFT JOIN |
我踩过的坑:忘记写 ON,结果学生表3行 × 成绩表3行 = 9行,完全乱了套。后来才知道那叫“笛卡尔积”,吓得我赶紧加上条件。
八、学习心得
📝 核心总结:
- INNER JOIN = 都要有 = 交集
- LEFT JOIN = 左表全 = 左边的都要
- RIGHT JOIN = 右表全 = 右边的都要
💡 实用建议:
- 80%的场景用LEFT JOIN(查主表所有数据)
- INNER JOIN用于筛选(只查匹配的数据)
- RIGHT JOIN用得少(可以用LEFT JOIN反过来写)
👋 我是数据库小学妹,一个每天都在和SQL语句"较劲"的数据库小白。我们一起把看似复杂的技术,变得简单有趣!💪