数据库关系代数中除运算讲解和SQL语句的实现
2016-12-21 18:35
519 查看
【数据库原理】关系代数篇——除法讲解
陈宇超 编辑总结:
除法运算的一般形式示意图
如何计算R÷S呢,首先我们引进”象集”的概念,具体意义看下面的陈述即可理解
关系R和关系S拥有共同的属性B、C
, R÷S得到的属性值就是关系R包含而关系S不包含的属性,即A属性
在R关系中A属性的值可以取{ a1,a2,a3,a4 }
a1值对应的象集为 { (b1,c2) , (b2,c1) , (b2,c3) }
a2值对应的象集为 { (b3,c7) , (b2,c3) }
a3值对应的象集为 { (b4,c6) }
a4值对应的象集为 { (b6,c6) }
关系S在B、C上的投影为
{ (b1,c2) , (b2,c1) , (b2,c3) }
只有a1值对应的象集包含关系S的投影集,所以只有a1应该包含在A属性中
所以R÷S为
【例题一】为了更好的理解除法的实际作用,请看下面的例题
设有教学数据库有3个关系(以下四小问均用除法的思想解决)
学生信息关系student(sno,sname,age,sex)
学生选课关系 sc(sno,cno,score)
学校课程关系 course(cno,cname)
Student表
Course表
SC表
SQL语言中没有全称量词,具体实现时可以把带有全称量词的谓词转换为等价的带有存在量词的谓词。
解决这类的除法问题一般采用双嵌套notexists来实现带全称量词的查询解决所谓forall的问题。
(1) 检索所学课程包含了C002课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σcno=’C002’ (course) )
Sql语句
从略
(2) 求至少选择了C001和C003两门课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σcno=’C001’ or cno=’C003’(course) )
Sql语句
select distinct sno
from sc
A where not
exists
(
select * from course
B where cno in ('C002','C003') and
not exists
(
select * from sc
C where
A.sno=C.sno and B.cno=C.cno
)
)
也可以采用自连接
select
s1.sno from
( select * from
sc where cno='C001' ) as
s1,
( select * from sc where
cno='C003' )
as s2
where s1.sno=s2.sno
(3) 求至少学习了学生S003所学 课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σsno=’S003’ (sc) )
select
distinct sno from
sc A where
not exists
(
select * from
sc B where
sno='S003' and not exists
(
select *
from sc
C where A.sno=C.sno
and B.cno=C.cno
)
)
(4) 求选择了全部课程的学生的学号
解 此例的等价自然语义是,输出这样的学号,不存在某门课程在他的选课记录里没有选这门课
关系代数表达式:∏sno (sc÷∏cno(course) )
Sql语句
select distinctsno
from sc
A where not
exists
(
select
cno from course
B where
not exists
(
select * from
sc C
where C.sno=A.sno
and C.cno=B.cno
)
)
(5) 求选择了全部课程的学生的学号和姓名
解 关系代数表达式:∏sno,sname((student∞sc)÷∏cno(course) )
Sql语句
select sno,sname
from student
A where not
exists
(
select cno from course B where
not exists
(
select
* from
sc C where
C.sno=A.sno and C.cno=B.cno
)
)
以上小问用groupby结合count语句也是可以实现的,也更好理解一些。
例如
求选择了全部课程的学生学号
SELECT sno FROM ( SELECT
COUNT(*)
cnt, Sno
FROM SC
GROUP BY
sno ) T WHERE
cnt =(
SELECT COUNT(Cno
) FROM
COURSE )
求至少选择了C002和C003两门课程的学生学号
select sno from sc where
cno in('C002','C003') group
by sno
having COUNT(cno)=2
注意:但该方法对于一个学生多次选修一门课程的情况无法处理,需要对其中的 SC 关系用distinct进行一定的预处理,所以group by+ count 有一定的局限性
陈宇超 编辑总结:
除法运算的一般形式示意图
如何计算R÷S呢,首先我们引进”象集”的概念,具体意义看下面的陈述即可理解
关系R和关系S拥有共同的属性B、C
, R÷S得到的属性值就是关系R包含而关系S不包含的属性,即A属性
在R关系中A属性的值可以取{ a1,a2,a3,a4 }
a1值对应的象集为 { (b1,c2) , (b2,c1) , (b2,c3) }
a2值对应的象集为 { (b3,c7) , (b2,c3) }
a3值对应的象集为 { (b4,c6) }
a4值对应的象集为 { (b6,c6) }
关系S在B、C上的投影为
{ (b1,c2) , (b2,c1) , (b2,c3) }
只有a1值对应的象集包含关系S的投影集,所以只有a1应该包含在A属性中
所以R÷S为
A |
a1 |
【例题一】为了更好的理解除法的实际作用,请看下面的例题
设有教学数据库有3个关系(以下四小问均用除法的思想解决)
学生信息关系student(sno,sname,age,sex)
学生选课关系 sc(sno,cno,score)
学校课程关系 course(cno,cname)
Student表
sno | sname | age | sex |
S001 | 陈晓 | 16 | 男 |
S002 | 周倩 | 21 | 女 |
S003 | 华南 | 19 | 男 |
S004 | 曹匀 | 21 | 女 |
S005 | 郑威 | 20 | 男 |
cno | cname |
C001 | 计算机科学 |
C002 | 诗歌鉴赏 |
C003 | 资本论 |
sno | cno | score |
S001 | C001 | 88 |
S001 | C002 | 95 |
S001 | C003 | 99 |
S002 | C001 | 97 |
S002 | C003 | 84 |
S003 | C002 | 69 |
S005 | C002 | 77 |
S005 | C003 | 98 |
SQL语言中没有全称量词,具体实现时可以把带有全称量词的谓词转换为等价的带有存在量词的谓词。
解决这类的除法问题一般采用双嵌套notexists来实现带全称量词的查询解决所谓forall的问题。
(1) 检索所学课程包含了C002课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σcno=’C002’ (course) )
Sql语句
从略
(2) 求至少选择了C001和C003两门课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σcno=’C001’ or cno=’C003’(course) )
Sql语句
select distinct sno
from sc
A where not
exists
(
select * from course
B where cno in ('C002','C003') and
not exists
(
select * from sc
C where
A.sno=C.sno and B.cno=C.cno
)
)
也可以采用自连接
select
s1.sno from
( select * from
sc where cno='C001' ) as
s1,
( select * from sc where
cno='C003' )
as s2
where s1.sno=s2.sno
(3) 求至少学习了学生S003所学 课程的学生学号
解 关系代数表达式:∏sno ( sc÷∏cno(σsno=’S003’ (sc) )
select
distinct sno from
sc A where
not exists
(
select * from
sc B where
sno='S003' and not exists
(
select *
from sc
C where A.sno=C.sno
and B.cno=C.cno
)
)
(4) 求选择了全部课程的学生的学号
解 此例的等价自然语义是,输出这样的学号,不存在某门课程在他的选课记录里没有选这门课
关系代数表达式:∏sno (sc÷∏cno(course) )
Sql语句
select distinctsno
from sc
A where not
exists
(
select
cno from course
B where
not exists
(
select * from
sc C
where C.sno=A.sno
and C.cno=B.cno
)
)
(5) 求选择了全部课程的学生的学号和姓名
解 关系代数表达式:∏sno,sname((student∞sc)÷∏cno(course) )
Sql语句
select sno,sname
from student
A where not
exists
(
select cno from course B where
not exists
(
select
* from
sc C where
C.sno=A.sno and C.cno=B.cno
)
)
以上小问用groupby结合count语句也是可以实现的,也更好理解一些。
例如
求选择了全部课程的学生学号
SELECT sno FROM ( SELECT
COUNT(*)
cnt, Sno
FROM SC
GROUP BY
sno ) T WHERE
cnt =(
SELECT COUNT(Cno
) FROM
COURSE )
求至少选择了C002和C003两门课程的学生学号
select sno from sc where
cno in('C002','C003') group
by sno
having COUNT(cno)=2
注意:但该方法对于一个学生多次选修一门课程的情况无法处理,需要对其中的 SC 关系用distinct进行一定的预处理,所以group by+ count 有一定的局限性
相关文章推荐
- ASP实现SQL语句日期格式的加减运算
- SQL语句实现关系代数中的“除法”
- ASP实现SQL语句日期格式的加减运算
- ASP实现SQL语句日期格式的加减运算
- 数据库除法的讲解和 sql 语句 not exist 实现
- SQL语句(十六)实现集合运算、对数据修改、数据表复制
- 以二进制形式将图片保存到数据库,用存诸过程实现(完整代码+sql语句)
- 用sql语句实现按时间求累计值
- 实现数据分类汇总的SQL语句
- [导入]实现SQL语句中,按照in 中的顺序排序的方法
- 使用SQL语句实现SPLIT效果的几种方法
- Sql 语句实现在同一个DB中复制表和空清一个DataTable中的所有数据
- 用T-SQL语句实现SQL server与XLS,MDB等文件的数据交换
- SQL语句实现横排?(转帖)
- SQL语句实现横排 2
- 更改表字段的描述 SQL语句实现
- .Net 分页实现系列之二基于sql语句分页的方式
- 实现数据分类汇总的SQL语句
- 用标准的SQL语句实现查询记录分页
- 使用Sql语句实现AspNetPager分页的范例