您的位置:首页 > 数据库

数据库关系代数中除运算讲解和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为

                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

Course表

                         cno                            
                      cname                      
C001
计算机科学
C002
诗歌鉴赏
C003
资本论
SC表

                         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 有一定的局限性
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息