关系代数验算 除法
2017-06-19 19:24
183 查看
除法是个比较难的关系代数运算
首先看一下定义
除运算同时从水平方向和垂直方向上进行运算 对于R(X,Y) S(Y,Z)来说 R/S是 这样的意义 对于X,Y-Y=X来说, X上的分量x在结果中当且仅当x在R上对于Y的象集Yx是S在Y上的投影
运算公式为 r(R) s(S)
r / s = r(R-S) - π(R-S){ π(R-S)(r)*s - π(R-S, S)r }
除法运算的一般形式示意图
如何计算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 distinctsno
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 distinctsno
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 C
首先看一下定义
除运算同时从水平方向和垂直方向上进行运算 对于R(X,Y) S(Y,Z)来说 R/S是 这样的意义 对于X,Y-Y=X来说, X上的分量x在结果中当且仅当x在R上对于Y的象集Yx是S在Y上的投影
运算公式为 r(R) s(S)
r / s = r(R-S) - π(R-S){ π(R-S)(r)*s - π(R-S, S)r }
除法运算的一般形式示意图
如何计算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 distinctsno
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 distinctsno
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 C