第14周 多表联结查询与组合查询
第14周 · 多表联结查询与组合查询
关系型数据库把数据拆到多张表(范式),成绩表 sc 里只有学号 sid,没有姓名。要"学号+姓名+成绩"一起看,就得把表连起来——这就是 JOIN。这周学内联结、外联结和 UNION 组合查询。
一、知识点:为什么需要联结
student存学生信息(sid, sname)sc存成绩(sid, cid, grade)
sc 里没姓名,靠 sid 这个共同列把两表关联,才能"按姓名看成绩"。联结的本质:用共同列把多张表的行拼成一行。
二、操作教程:INNER JOIN 内连接
只返回两表都匹配的行(交集):
SELECT s.sname, sc.cid, sc.grade
FROM student s
JOIN sc ON s.sid = sc.sid;
JOIN默认就是INNER JOIN。ON后面写联结条件(两张表怎么对上)。s是student的别名,省得写全名。
结果(5 行:有成绩的学生):张伟/李娜/王芳 各自的选课。
三、操作教程:LEFT / RIGHT JOIN 外连接
-- 左外连接:左表(student)全部保留,右表没匹配的填 NULL
SELECT s.sname, sc.cid, sc.grade
FROM student s
LEFT JOIN sc ON s.sid = sc.sid;
| 类型 | 含义 |
|---|---|
LEFT JOIN |
保留左表全部行,右表无匹配补 NULL |
RIGHT JOIN |
保留右表全部行,左表无匹配补 NULL |
示例:刘强没选课,LEFT JOIN 仍列出他,cid/grade 显示 NULL;若用 INNER JOIN 则刘强直接不出现。
记住:
LEFT JOIN看的是"左表全不全",常用来查"某某没有…"的问题(如没选课的学生)。
四、知识点:ON 与 WHERE 的区别(重点)
ON:写联结条件(表怎么连),在连接时发生作用。WHERE:写筛选条件(连完之后过滤行)。
常见错误:把联结条件误放 WHERE,若两表无匹配会丢数据甚至产生笛卡尔积。规范写法:
SELECT s.sname, sc.grade
FROM student s
LEFT JOIN sc ON s.sid = sc.sid -- 联结条件放 ON
WHERE sc.grade > 80; -- 筛选条件放 WHERE
LEFT JOIN时若把"右表筛选"写在WHERE(如WHERE sc.cid=1),会把 NULL 行也过滤掉,变成和内连接一样。要保留左表全行,右表条件应放ON。
五、操作教程:三表联结
学生+成绩+课程一起看:
SELECT s.sname, c.cname, sc.grade
FROM student s
JOIN sc ON s.sid = sc.sid
JOIN course c ON sc.cid = c.cid;
多表联结就是"链"式
JOIN,每次用一个共同列接下一张表。
六、知识点:UNION 组合查询
UNION 把两个 SELECT 的结果上下拼起来(列数必须一致),并自动去重;UNION ALL 不去重、效率更高。
-- 计算机系学生 与 年龄>20 学生 的并集(去重)
SELECT sname FROM student WHERE sdept='计算机系'
UNION
SELECT sname FROM student WHERE sage > 20;
UNION要求两个查询列数相同、对应列类型兼容。想去重保留全部重复用UNION ALL。
七、综合实操:作业三题
-- 题1:内连接,姓名+课程号+成绩
SELECT s.sname, sc.cid, sc.grade
FROM student s
JOIN sc ON s.sid = sc.sid;
-- 题2:左外连接,含未选课学生(NULL 补全)
SELECT s.sname, sc.cid, sc.grade
FROM student s
LEFT JOIN sc ON s.sid = sc.sid;
-- 题3:UNION 组合(计算机系 ∪ 年龄>20)
SELECT sname FROM student WHERE sdept='计算机系'
UNION
SELECT sname FROM student WHERE sage > 20;
八、易混点排查表
| 现象 | 解决方法 |
|---|---|
| 结果行数异常多(笛卡尔积) | 漏写 ON 联结条件;补 ON 表1.列=表2.列 |
| 左连接后 NULL 行没了 | 右表筛选误放 WHERE;改放 ON |
| INNER 和 LEFT 结果一样 | 确认是否真有"无匹配"的行;有才看出差别 |
| UNION 报错列数不同 | 两个 SELECT 列数必须一致 |
| UNION 想保留重复却没了 | 用 UNION ALL |
| 分不清左右 | LEFT 保左表,RIGHT 保右表;常用 LEFT |
九、小测验(自测)
- 查"姓名+课程号+成绩"用内连接怎么写?
ON后面写的是什么? LEFT JOIN和INNER JOIN结果有什么区别?什么场景必须用 LEFT JOIN?ON和WHERE分别写什么条件?为什么 LEFT JOIN 的右表筛选不能放 WHERE?UNION和UNION ALL的区别?用 UNION 拼两个查询结果有什么要求?
【声明】本文由 AI 辅助生成,仅供 MySQL 数据库教学参考,如有疑误以教材为准。
浙公网安备 33010602011771号