首页 / 数据库原理与应用 / SQL数据查询语言DQL(多表连接查询)

第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:右圆全部 + 交集

自学自检小问题

  1. INNER JOIN和LEFT JOIN的结果有什么区别?
  2. 三表连接时,需要写几个JOIN条件?
  3. 什么情况下会产生笛卡尔积?如何避免?

拓展学习资源

第5章 基础巩固练习
0/5
第1题 选择题
在SQL中,内连接使用的关键字是( )
LEFT JOIN
RIGHT JOIN
INNER JOIN
FULL JOIN
答案解析
正确答案:C(INNER JOIN)。INNER JOIN返回两个表中匹配的记录。
第2题 选择题
要返回左表所有记录,右表不匹配的记录用NULL填充,应使用( )
INNER JOIN
LEFT JOIN
RIGHT JOIN
CROSS JOIN
答案解析
正确答案:B(LEFT JOIN)。LEFT JOIN保证左表所有记录都出现在结果中。
第3题 选择题
三表连接查询时,至少需要几个JOIN条件?( )
1个
2个
3个
不需要
答案解析
正确答案:B(2个)。N个表连接至少需要N-1个连接条件。
第4题 选择题
笛卡尔积产生的原因是( )
使用了INNER JOIN
['没有写连接条件']
使用了LEFT JOIN
使用了WHERE
答案解析
正确答案:B(没有写连接条件)。没有连接条件时,每张表的每行都会与其他表的每行组合。
第5题 选择题
查询没有选修任何课程的学生,应使用( )
INNER JOIN
LEFT JOIN ... WHERE ... IS NULL
RIGHT JOIN
CROSS JOIN
答案解析
正确答案:B。LEFT JOIN左表所有记录,右表不匹配的为NULL,通过IS NULL筛选即可。
0/0