第5章 SQL数据查询语言DQL(多表连接查询)
5.1 为什么需要多表查询
实际业务数据分散在多个表中,需要关联查询获取完整信息。例如,要查询学生姓名和课程名称,就需要连接student、sc和course三张表。
5.2 内连接(INNER JOIN)
只返回两个表中匹配的记录。不匹配的记录不会出现在结果中。
SELECT s.sname, c.cname, sc.grade
FROM student s
INNER JOIN sc ON s.sno = sc.sno
INNER JOIN course c ON sc.cno = c.cno;
5.3 左连接(LEFT JOIN)
返回左表所有记录,右表不匹配的记录用NULL填充。
-- 查询所有学生及其选课信息(包括没选课的学生)
SELECT s.sname, c.cname, sc.grade
FROM student s
LEFT JOIN sc ON s.sno = sc.sno
LEFT JOIN course c ON sc.cno = c.cno;
5.4 右连接(RIGHT JOIN)
返回右表所有记录,左表不匹配的记录用NULL填充。
-- 查询所有课程及选课学生(包括没人选的课程)
SELECT c.cname, s.sname, sc.grade
FROM student s
RIGHT JOIN sc ON s.sno = sc.sno
RIGHT JOIN course c ON sc.cno = c.cno;
5.5 笛卡尔积
没有连接条件的两表相乘,结果集行数=表1行数 x 表2行数,通常需要避免。
-- 笛卡尔积(应避免)
SELECT * FROM student, sc; -- 没有WHERE条件
5.6 表别名
给表起短名简化书写。
SELECT s.sname, c.cname
FROM student s
JOIN sc ON s.sno = sc.sno
JOIN course c ON sc.cno = c.cno;
5.7 自连接
一个表与自身连接,常用于查询层级关系数据。
-- 查询与"张三"同系的学生
SELECT s2.sname
FROM student s1
JOIN student s2 ON s1.sdept = s2.sdept
WHERE s1.sname = '张三' AND s2.sname != '张三';
5.8 连接类型对比(Venn图理解)
- INNER JOIN:两个圆的交集部分
- LEFT JOIN:左圆全部 + 交集
- RIGHT JOIN:右圆全部 + 交集
自学自检小问题
- INNER JOIN和LEFT JOIN的结果有什么区别?
- 三表连接时,需要写几个JOIN条件?
- 什么情况下会产生笛卡尔积?如何避免?
拓展学习资源
- 菜鸟教程:MySQL连接查询
- 实训数据集:学生表、课程表、成绩表、教师表
第5章 基础巩固练习
0/5
第1题
选择题
在SQL中,内连接使用的关键字是( )
答案解析
正确答案:C(INNER JOIN)。INNER JOIN返回两个表中匹配的记录。
第2题
选择题
要返回左表所有记录,右表不匹配的记录用NULL填充,应使用( )
答案解析
正确答案:B(LEFT JOIN)。LEFT JOIN保证左表所有记录都出现在结果中。
第3题
选择题
三表连接查询时,至少需要几个JOIN条件?( )
答案解析
正确答案:B(2个)。N个表连接至少需要N-1个连接条件。
第4题
选择题
笛卡尔积产生的原因是( )
答案解析
正确答案:B(没有写连接条件)。没有连接条件时,每张表的每行都会与其他表的每行组合。
第5题
选择题
查询没有选修任何课程的学生,应使用( )
答案解析
正确答案:B。LEFT JOIN左表所有记录,右表不匹配的为NULL,通过IS NULL筛选即可。
0/0