# 关系代数与 sql
# 关系代数
- 关系代数简介
- 关系代数(Relational Algebra, RA) 是针对关系模型的操作语言。
- 关系代数由一组操作符组成,可以对关系(表)执行操作,描述如何一步一步计算出所需结果。
- 关系代数是命令式的,描述了查询的过程,而不是结果的约束。
- 关系代数基本操作符
选择 (Selection, σ):
- 选择操作从一个关系(表)中挑选出符合某个条件的元组(行)。
- 形式:σ_condition (R)
- 示例:σ_country='AUS'(Student) 会返回所有国家为 “澳大利亚” 的学生。
投影 (Projection, π):
- 投影操作从一个关系中选择特定的属性(列),并删除重复的元组。
- 形式:π_attributes (R)
- 示例:π_name, country (Student) 返回学生表中的姓名和国家列,去除重复值。
笛卡尔积 (Cross Product, ×):
- 笛卡尔积操作将两个关系的所有元组进行组合,形成新的关系,结果的每一行都是两个关系中元组的所有可能组合。比如学生表有 2 条数据,老师表有 3 条数据,组成的新表就有 6 条数据。
- 形式:R × S
- 示例:Student × Enrolled 将两个表中的每一个元组组合在一起。
联合 (Union, ∪):
- 联合操作返回两个关系中的所有元组,自动去除重复的行。
- 形式:R ∪ S
- 示例:π_sid (Student) ∪ π_sid (Enrolled) 返回在学生和选课表中出现的所有学生 ID。
交集 (Intersection, ∩):
- 交集操作返回在两个关系中都存在的元组。
- 形式:R ∩ S
- 示例:π_sid (Student) ∩ π_sid (Enrolled) 返回同时出现在学生表和选课表中的学生 ID。
差集 (Difference, −):
- 差集操作返回在第一个关系中存在但在第二个关系中不存在的元组。
- 形式:R − S
- 示例:π_sid (Student) − π_sid (Enrolled) 返回只在学生表中存在而没有选课的学生 ID。
- 连接操作
# 连接操作
- 条件连接 (Theta Join, ⋈ₛ)
定义:条件连接是基于给定的条件,将两个关系的笛卡尔积中的行进行筛选。该条件可以是任意的布尔表达式(例如
=
、>
、<
等比较操作符)。形式:
R ⋈ₛ S
,其中ₛ
是连接条件。示例:假设有两个表
Student
和Enrolled
,我们希望查找学生和他们所选的课程:- 表
Student
:
- 表
sid | name | country |
---|---|---|
1001 | lan | AUS |
1002 | Ha | ROK |
- 表 `Enrolled`:
sid | uos_code |
---|---|
1001 | COMP5318 |
1002 | COMP5318 |
查询学生与他们所选课程,可以使用 sid
作为连接条件:
- `Student ⋈_{Student.sid = Enrolled.sid} Enrolled`:
sid | name | country | uos_code |
---|---|---|---|
1001 | lan | AUS | COMP5318 |
1002 | Ha | ROK | COMP5318 |
- 通过这个操作,我们得到了两个表中
sid
匹配的行。
- 自然连接 (Natural Join, ⋈)
定义:自然连接是一种特殊的等值连接,它自动基于两个关系中具有相同名称且值相等的属性进行连接,且在结果中只保留一个重复的属性列。
形式:
R ⋈ S
,连接条件是所有同名属性相等。示例:考虑前面的
Student
和Enrolled
表,假设我们要进行自然连接:Student ⋈ Enrolled
:
sid | name | country | uos_code |
---|---|---|---|
1001 | lan | AUS | COMP5318 |
1002 | Ha | ROK | COMP5318 |
- 在自然连接中,
sid
是两个表中共有的属性,连接后只保留一列sid
。
- 等值连接 (Equi-Join)
- 定义:等值连接是条件连接的一种特例,连接条件只包含相等比较(
=
)。 - 形式:
R ⋈_{A = B} S
,其中A
和B
是两个表中的属性。 - 与自然连接的区别:等值连接会保留连接条件中的重复属性,而自然连接则去掉重复列。
- 示例:
Student ⋈_{Student.sid = Enrolled.sid} Enrolled
,结果中会保留两个sid
列。
- 外连接 (Outer Join)
外连接允许在结果中包含没有匹配行的元组,并填充相应部分为 NULL
。
左外连接 (Left Outer Join):返回左表中的所有元组,即使右表中没有匹配的行。
- 形式:
R LEFT OUTER JOIN S
。 - 示例:
Student LEFT OUTER JOIN Enrolled
会返回学生表中的所有行,即使有些学生没有选课,未匹配的部分用NULL
填充:
- 形式:
sid | name | country | uos_code |
---|---|---|---|
1001 | lan | AUS | COMP5318 |
1002 | HA | ROK | COMP5318 |
1003 | Grant | AUS | NULL |
右外连接 (Right Outer Join):返回右表中的所有元组,即使左表中没有匹配的行。
- 形式:
R RIGHT OUTER JOIN S
。
- 形式:
全外连接 (Full Outer Join):返回两个表中的所有元组,包括没有匹配的行,并将未匹配的部分用
NULL
填充。- 形式:
R FULL OUTER JOIN S
。
- 形式:
# SQL 简介
在 SQL 中,集合操作用于对两个查询结果集进行运算,类似于关系代数中的集合运算。常见的 SQL 集合操作包括 UNION
、 INTERSECT
和 EXCEPT
。这些操作用于合并、比较两个查询的结果集,并遵循集合的基本规则,如去除重复数据。每个操作都需要两个结果集具有相同数量的列,且相应列的数据类型必须兼容。
# 1. UNION(并集)
UNION
操作返回两个查询结果的并集,也就是说,它会包含两个结果集中所有的行,且自动去除重复的行。
语法:
row 1
2
3
4
5SELECT 列1, 列2, ...
FROM 表1
UNION
SELECT 列1, 列2, ...
FROM 表2;示例:
row 1
2
3SELECT name FROM Students
UNION
SELECT name FROM Teachers;该查询将返回
Students
表和Teachers
表中的所有不同的名字(去重)。特点:
- 自动去除重复行。
- 可以使用
UNION ALL
来保留重复行。
示例:
row 1
2
3SELECT name FROM Students
UNION ALL
SELECT name FROM Teachers;
UNION ALL
将返回所有行,包括重复的行。
# 2. **INTERSECT(** 交集)
INTERSECT
操作返回两个查询结果的交集,即只返回在两个查询结果中都存在的行。
语法:
row 1
2
3
4
5
6SELECT 列1, 列2, ...
FROM 表1
INTERSECT
SELECT 列1, 列2, ...
FROM 表2;示例
row 1
2
3
4SELECT name FROM Students
INTERSECT
SELECT name FROM Teachers;该查询将返回既是
Students
表又是Teachers
表中的名字(即两个表中都存在的名字)。特点:
- 只返回两个结果集中都出现的行。
- 自动去除重复行。
# 3. EXCEPT(差集)
EXCEPT
操作返回在第一个查询结果中存在但在第二个查询结果中不存在的行。
语法:
row 1
2
3
4
5
6SELECT 列1, 列2, ...
FROM 表1
EXCEPT
SELECT 列1, 列2, ...
FROM 表2;示例
row 1
2
3
4SELECT name FROM Students
EXCEPT
SELECT name FROM Teachers;该查询将返回所有只存在于
Students
表中但不在Teachers
表中的名字。特点:
- 返回只出现在第一个结果集中的行。
- 自动去除重复行。
# 4. UNION、INTERSECT 和 EXCEPT 的规则:
- 列数必须相同:在两个查询中,
SELECT
子句中的列数量必须一致。 - 数据类型必须兼容:相应列的数据类型必须相同或兼容。
- 去除重复行:默认情况下,
UNION
、INTERSECT
和EXCEPT
都会去除重复的行。 - 使用 ALL 保留重复行:如果希望保留重复行,可以使用
UNION ALL
,但INTERSECT ALL
和EXCEPT ALL
在部分 SQL 实现中并不支持。
# 总结:
UNION
返回两个查询结果集的并集,去除重复行。INTERSECT
返回两个查询结果集的交集,即共同存在的行。EXCEPT
返回第一个结果集中有但第二个结果集中没有的行。