数据库系统概论(九)SQL连接查询语言超详细讲解(附带例题,表格详细讲解对比带你一步步掌握)
数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)
- 前言
- 一、关系代数中的连接运算是什么
- 1. 一般连接(条件连接)
- 2. 等值连接
- 3. 自然连接
- 4. 外连接(保留未匹配的行)
- 1. 左外连接
- 2. 右外连接
- 3. 全外连接
- 总结
- 二、连接查询是什么
- 1. 什么是连接查询?
- 2. 为什么需要连接查询?
- 3. 连接查询的基本结构
- 1. FROM子句:告诉计算机要查哪些表
- 2. WHERE子句:告诉计算机如何“连接”表
- 4. 连接字段的要求
- 5. 总结
- 三、连接查询
- 1. 等值与非等值的连接查询
- 2. 自然连接查询
- 3. 复合条件连接查询
- 4. 自身连接查询
- 5.外连接查询
- 1. 外连接与普通连接的区别
- 2. 外连接的类型
- 3. MySQL 外连接语法
- 6. 多表连接查询
- 1. 什么是多表连接?
- 2. 多表连接的两种写法
- 3. 多表连接示例
- 4. 多表连接的注意事项
前言
- 之前我们已经简单认识了 SQL 语言(结构化查询语言),并了解了它的基本概念(比如表、元组、属性、数据库等)。
- 现在,我们正式进入 SQL 核心功能 的学习 —— SQL 查询语言,这是日常使用最频繁、也是掌握 SQL 的关键部分。
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的数据库系统概论专栏
https://blog.csdn.net/2402_83322742/category_12911520.html?spm=1001.2014.3001.5482
一、关系代数中的连接运算是什么
- 关系代数中的连接运算,简单来说就是把两个表格(关系)按一定规则拼起来,生成一个新表格。
- 不同的连接方式决定了“拼的规则”和“如何处理拼不上的行”。
1. 一般连接(条件连接)
规则:按你指定的任意条件(比如“相等”“大于”“小于”等)拼接两个表格。
例子:
- 表格R(学生表):包含“学号”“姓名”列
- 表格S(成绩表):包含“学号”“成绩”列
- 想找出成绩大于80分的学生,用一般连接:
R ⋈(R.学号=S.学号 AND S.成绩>80) S
结果:只显示学号匹配且成绩>80的学生及其成绩。
特点:条件灵活,用θ
表示任意比较符(如=
、>
、<
),所以也叫“θ连接”。
2. 等值连接
规则:专门用等于号(=)作为条件的一般连接,即只拼接两表中指定列值相等的行。
例子:
- 想拼接学生表和成绩表(按学号相等):
R ⋈(R.学号=S.学号) S
结果:显示所有学号匹配的学生和成绩,但会保留两表中重复的“学号”列(如R.学号和S.学号)。
特点:是一般连接的特例,条件只能是“等于”,结果可能有重复列。
3. 自然连接
规则:
- 自动按两表中 名称相同的列(如都有“学号”列)进行等值连接;
- 自动去重:合并重复的列名,只保留一列。
例子:
- 学生表(学号,姓名)和成绩表(学号,成绩)做自然连接:
R ⋈ S
结果:直接按“学号”相等拼接,结果列为学号、姓名、成绩(无重复学号列)。
特点: - 无需手动写条件,只要列名相同就自动连接;
- 结果更简洁,重复列只留一个。
注意:如果两表没有同名列,自然连接会变成笛卡尔积(所有行互相拼接),这一般不是你想要的!
4. 外连接(保留未匹配的行)
前面的连接会丢弃两表中无法匹配的行,而外连接会保留这些行,用NULL
(空值)填充无法匹配的列。
1. 左外连接
规则:保留左边表的所有行,右边表中无法匹配的行用NULL
填充。
例子:
- 想显示所有学生(包括没成绩的):
R 左外连接 S
结果:- 有成绩的学生:正常显示姓名和成绩;
- 没成绩的学生:成绩列为
NULL
。
2. 右外连接
规则:保留右边表的所有行,左边表中无法匹配的行用NULL
填充。
例子:
- 想显示所有成绩(包括没对应学生的):
R 右外连接 S
结果:- 有学生的成绩:正常显示姓名和成绩;
- 没学生的成绩:姓名列为
NULL
。
3. 全外连接
规则:保留左右两表的所有行,两边无法匹配的行都用NULL
填充。
结果:相当于左外连接和右外连接的合并。
总结
连接类型 | 核心规则 | 是否保留未匹配行 | 重复列处理 |
---|---|---|---|
一般连接 | 按任意条件(如A> B)拼接匹配行 | 否 | 保留所有列 |
等值连接 | 按“等于”条件拼接匹配行 | 否 | 保留重复列 |
自然连接 | 按同名列自动等值连接,去重重复列 | 否 | 去重同名列 |
左外连接 | 保留左表所有行,右表不匹配行填NULL | 是(左表全保留) | 同等值连接 |
右外连接 | 保留右表所有行,左表不匹配行填NULL | 是(右表全保留) | 同等值连接 |
全外连接 | 保留两表所有行,不匹配行填NULL | 是(两表全保留) | 同等值连接 |
二、连接查询是什么
1. 什么是连接查询?
一句话总结:同时查询多个表的数据,就叫连接查询。
比如:想查「学生姓名」和「对应的课程成绩」,但「姓名」在学生表,「成绩」在课程表,这时候就需要把两个表「连起来」查。
2. 为什么需要连接查询?
场景举例:
- 学生表:存学生姓名、学号等信息。
- 课程表:存学号、课程名、成绩等信息。
- 如果想知道「张三的数学成绩」,就需要用「学号」把两个表连起来,才能拿到完整的信息。
3. 连接查询的基本结构
1. FROM子句:告诉计算机要查哪些表
SELECT ... FROM 表1, 表2; -- 最基础的写法,用逗号分隔多个表
注意:
- 可以是真实的表,也可以是视图(暂时先理解为“虚拟表”)。
- 表名太多时,建议用别名简化,比如:
SELECT ... FROM 学生表 AS s, 课程表 AS c; -- s和c是表的别名
2. WHERE子句:告诉计算机如何“连接”表
核心逻辑:用一个条件,把两个表中「有关系的数据」匹配起来。
格式1:用比较运算符(最常用)
WHERE 表1.字段 = 表2.字段; -- 最常见的是“等于”(=)
举例:用学号连接学生表和课程表
SELECT s.姓名, c.成绩
FROM 学生表 AS s, 课程表 AS c
WHERE s.学号 = c.学号; -- 连接条件:两个表的学号相等
格式2:用BETWEEN(较少用,了解即可)
WHERE 表1.字段 BETWEEN 表2.字段1 AND 表2.字段2;
举例:查价格在某个区间的商品(假设表1存商品名,表2存价格区间)
SELECT a.商品名
FROM 商品表 AS a, 价格表 AS b
WHERE a.价格 BETWEEN b.最低价格 AND b.最高价格;
4. 连接字段的要求
-
类型必须可比:
- 比如两个字段都是「整数」(学号)或都是「文本」(姓名),否则无法匹配。
- ✅ 正确:学生表.学号(整数)= 课程表.学号(整数)
- ❌ 错误:学生表.学号(整数)= 课程表.学号(文本)
-
名字可以不同:
- 只要含义一致,字段名可以不一样。
- 举例:学生表用「student_id」,课程表用「sid」,但都是学号,依然可以连接:
WHERE 学生表.student_id = 课程表.sid;
5. 总结
- 确定要查哪些表(写在FROM后面)。
- 找到表之间的关联字段(比如学号、订单号等)。
- 用WHERE子句写出连接条件(通常是「表1.字段 = 表2.字段」)。
三、连接查询
1. 等值与非等值的连接查询
在连接查询中,根据连接条件使用的运算符不同,可分为等值连接和非等值连接。
- 等值连接:当连接条件使用“=”运算符时,就叫做等值连接,这是最常用的连接方式。
- 它的作用是把两个表中连接字段值相等的记录匹配在一起。
- 比如,想知道每个学生的选课情况,学生信息在
Student
表,选课信息在SC
表,就可以用学号(Sno
)作为连接字段,把两个表中Sno
相同的记录对应起来,查询语句如下:
SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.Sno
这条语句会把Student
表和SC
表中Sno
相等的所有记录组合展示出来,*
表示显示两个表的所有列。
- 非等值连接:除了“=”之外,使用其他运算符(如
>
、<
、BETWEEN
等)进行连接条件判断的,就是非等值连接。例如,根据成绩区间来匹配学生和对应的课程评价,就可能用到BETWEEN
等非等值运算符,但日常使用频率相比等值连接要低一些。
2. 自然连接查询
自然连接是等值连接的“升级版”,它在等值连接的基础上,进一步优化了查询结果的展示。
- 核心特点:自然连接会自动去掉结果中重复的属性列,让查询结果更简洁清晰。
- 比如
Student
表和SC
表都有Sno
列,自然连接后,只会显示一个Sno
列。 - 使用要点:
- SELECT子句:手动选择不重复的列,避免重复显示连接字段。例如查询学生及其选课信息时,只选
Student.Sno
,而不是同时选Student.Sno
和SC.Sno
。 - WHERE子句:依然要包含等值连接条件,用来匹配两个表的记录,这和等值连接的条件写法一样。
- SELECT子句:手动选择不重复的列,避免重复显示连接字段。例如查询学生及其选课信息时,只选
- 示例:想查询每个学生的详细信息和选修课程的课程号与成绩,使用自然连接的SQL语句如下:
SELECT Student.Sno, Sname, Ssex, Sbirthdate, Smajor, Cno, Grade
FROM Student, SC
WHERE Student.Sno = SC.Sno;
这条语句通过Student.Sno = SC.Sno
进行等值连接,SELECT
子句选取了不重复且需要展示的列,最终得到简洁又完整的查询结果。
3. 复合条件连接查询
在实际查询中,我们常常不仅需要连接表,还想筛选出特定条件的数据,这时就需要 复合条件连接查询。
- 核心原理:在
WHERE
子句中,同时包含连接条件和选择条件,用AND
连接起来。- 连接条件:用于匹配多个表的关联字段(和前面的等值连接类似)。
- 选择条件:用于筛选出符合特定要求的记录(比如成绩大于90分、课程号等于某个值)。
- 举例:想查询选修了
81002
号课程且成绩在 90 分以上的学生学号和姓名,就需要:- 用
Student.Sno=SC.Sno
连接Student
表和SC
表(连接条件); - 用
SC.Cno='81002' AND SC.Grade>90
筛选出符合课程和成绩要求的记录(选择条件)。
这条语句会先把两个表连接起来,再筛选出同时满足三个条件的记录,最终只显示学号和姓名。SELECT Student.Sno, Sname FROM Student, SC WHERE Student.Sno=SC.Sno AND SC.Cno='81002' AND SC.Grade>90;
- 用
4. 自身连接查询
有时候,我们需要从 同一个表 中找出不同记录之间的关系,这时就需要 自身连接。
- 关键操作:给同一个表起 两个不同的别名,让它“扮演”两个角色,区分不同记录。
- 例如:把
Course
表命名为A
和B
,A
代表课程本身,B
代表课程的先修课。 - 因为属性名(如
Cno
、Cpno
)都相同,所以必须用别名前缀(A.Cno
、B.Cpno
)明确区分。
- 例如:把
- 应用场景举例:
- 查询课程的间接先修课:想知道每门课“先修课的先修课”,可以用自身连接:
这里用SELECT A.Cno, B.Cpno FROM Course A, Course B WHERE A.Cpno=B.Cno and B.Cpno IS NOT NULL
A.Cpno=B.Cno
连接A
和B
,表示A
的先修课是B
,再筛选出B
还有先修课(B.Cpno IS NOT NULL
)的记录。
2. 查询选修多门课的学生:想找出至少选修了 2 门课的学生学号,有两种方法:- 自身连接法:把
SC
表命名为A
和B
,通过A.Sno = B.Sno and A.Cno!= B.Cno
找出同一个学生选修的不同课程。
select distinct A.Sno from SC A, SC B where A.Sno = B.Sno and A.Cno!= B.Cno
- 分组统计法:用
GROUP BY
和HAVING
直接统计每个学生的选课数量。
select sno from sc group by sno having count(*)>=2
5.外连接查询
1. 外连接与普通连接的区别
- 普通连接:只输出满足连接条件的记录(两表匹配的部分)。
- 外连接:除了匹配的记录,还会保留某一侧表中不满足条件的记录,未匹配的字段用
NULL
填充。
2. 外连接的类型
-
左外连接(LEFT OUTER JOIN):保留左表的所有记录,右表无匹配的字段填
NULL
。
示例:查询所有学生及其选修课程(包括未选课的学生)SELECT Student.Sno, Sname, Cno, Grade FROM Student LEFT JOIN SC ON Student.Sno = SC.Sno;
- 即使学生未选课,左表(Student)的记录也会保留,右表(SC)字段为
NULL
。
- 即使学生未选课,左表(Student)的记录也会保留,右表(SC)字段为
-
右外连接(RIGHT OUTER JOIN):保留右表的所有记录,左表无匹配的字段填
NULL
。
示例:查询所有课程的选修成绩(包括未被选修的课程)SELECT Course.Cno, Cname, AVG(Grade) AS avg_grade FROM Course RIGHT JOIN SC ON Course.Cno = SC.Cno GROUP BY Course.Cno;
- 即使课程无人选修,右表(Course)的记录也会保留,左表(SC)字段为
NULL
。
- 即使课程无人选修,右表(Course)的记录也会保留,左表(SC)字段为
-
全外连接(FULL OUTER JOIN):保留左右两表的所有记录,无匹配的字段填
NULL
。
注意:MySQL 不支持全外连接,可通过UNION
合并左、右外连接结果实现。
3. MySQL 外连接语法
-- 左外连接
表1 LEFT JOIN 表2 ON 连接条件 -- 右外连接
表1 RIGHT JOIN 表2 ON 连接条件
6. 多表连接查询
1. 什么是多表连接?
- 对 3个或以上表 进行连接查询,需至少
n-1
个连接条件(n
为表的数量)。
2. 多表连接的两种写法
-
传统写法(逗号分隔表名,用 WHERE 指定条件)
示例:查询学生学号、姓名、课程名及成绩SELECT Student.Sno, Sname, Cname, Grade FROM Student, SC, Course WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;
-
JOIN…ON 写法(更清晰)
SELECT Student.Sno, Sname, Cname, Grade FROM Student JOIN SC ON Student.Sno = SC.Sno -- 学生表与选课表连接 JOIN Course ON SC.Cno = Course.Cno; -- 选课表与课程表连接
3. 多表连接示例
场景:查询计算机专业学生选修“数据库系统概论”的成绩,按成绩降序排列
SELECT SC.Sno, Sname, Grade
FROM Student, SC, Course
WHERE Student.Sno = SC.Sno AND -- 学生表与选课表连接SC.Cno = Course.Cno AND -- 选课表与课程表连接Cname = '数据库系统概论' AND -- 筛选课程名Smajor = '计算机科学与技术' -- 筛选专业
ORDER BY Grade DESC; -- 按成绩降序
4. 多表连接的注意事项
- 连接顺序:先连接两张表,再逐步添加其他表,避免笛卡尔积(结果行数爆炸)。
- 别名简化:给表起短别名(如
Student AS S
),方便书写和阅读。 - 条件完整性:确保每个表都通过连接条件关联,否则会生成无意义的笛卡尔积。
以上就是这篇博客的全部内容,下一篇我们将继续探索更多精彩内容。
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的数据库系统概论专栏
https://blog.csdn.net/2402_83322742/category_12911520.html?spm=1001.2014.3001.5482
非常感谢您的阅读,喜欢的话记得三连哦 |