数据库关系代数中除运算讲解和SQL语句的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22627687/article/details/53789362

【数据库原理】关系代数篇——除法讲解

                                                                                                                                                                                                                                                           陈宇超   编辑总结:

除法运算的一般形式示意图

 

如何计算R÷S呢,首先我们引进”象集”的概念,具体意义看下面的陈述即可理解

关系R和关系S拥有共同的属性BC , 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)  }

关系SBC上的投影为 {  (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  )

求至少选择了C002C003两门课程的学生学号

select   sno   from  sc  where cno   in('C002','C003')   group by   sno   having COUNT(cno)=2

注意:但该方法对于一个学生多次选修一门课程的情况无法处理,需要对其中的 SC 关系用distinct进行一定的预处理,所以group by+ count 有一定的局限性

 

猜你喜欢

转载自blog.csdn.net/qq_22627687/article/details/53789362