在SQL中无全称量词,因此,在解决相关的查询问题中,我们一般将带有全称量词的谓词转换成等价的带有存在量词的谓词问题。因此本文将基于学生—课程数据库中的三个基本表进行相关总结。
学生表 student(sno,sname,ssex,sage,sdept)
课程表course(cno,cname,cpno,ccredit)
选课表sc(sno,cno,grade)
例1.查询选修了全部课程的学生姓名。
根据语义:所有的课程这位学生都选修了。
即:
其中x表示实际有的任意一门选修课。
P表示该学生选修了x。
于是,上述全程量词问题可以转换为:对任意一门课程x,该学生都选修了。
等价于:不存在一门课程,该学生没有选修。
于是可以得出相应问题的SQL语句如下:
SELECT sname
FROM student
WHERE NOT EXISTS
(SELECT *
FROM course
WHERE NOT EXISTS
(SELECT *
FROM sc
WHERE sno=student.sno
AND cno=course.cno));
总:仔细观察,对应的SQL语句与相应的语义转化具有一致性。因此,解决此类问题的关键在于根据问题意思将原问题转化为含存在量词的等价问题。
例2.查询至少选修了学生201215122选修的全部课程的学生学号。
原问题的意思是:
对于学校的任意一门选修课y,如果学生201215122选修了y,那么要查询的学生也选修了y。
即:
其中,y表示学校任意一门选修课,P表示学生201215122选修了y,q表示要查询的学生也选修了y。
问题的等价转换语义为:不存在一门课程y,学生201215122选修了,但同时要查询的学生却没有选修。
于是可以得到如下SQL语句:
SELECT sno
FROM sc scx
WHERE NOT EXISTS
(SELECT *
FROM sc scy
WHERE sno='201215122'
AND NOT EXISTS
(SELECT *
FROM sc scz
WHERE scz.sno=scx.sno
AND scz.cno=scy.cno));
总:以上问题为SQL中的逻辑蕴涵问题,问题的关键还是在于将原问题等价转换,之后即可根据转换后的语义很快的写出代码。
下面,我们再看几个相关问题。
例3.选择选修了学号为201215123学生选修的全部课程的学生的学号与姓名。
SELECT scx.sno,sname
FROM student,sc scx
WHERE student.sno=scx.sno/*将学生表与选课表按学号连接*/
AND NOT EXISTS
(SELECT*
FROM sc scy
WHERE scy='201215123'
AND NOT EXISTS
(SELECT *
FROM sc scz
WHERE scz.cno=scy.cno
AND scz.sno=scx.sno));
总:此问题与例2问题的区别在于:查询涉及到了学生表与选课表两个基本表。其它思路与例2类似。
例4.查询全部学生都选修了的课程号与课程名。
转化后等价语义为:对于要查询的课程,不存在学生没有选修。
SELECT cno,cname
FROM course
WHERE NOT EXISTS
(SELECT *
FROM student
WHERE NOT EXISTS
(SELECT *
FROM sc
WHERE sc.cno=course.cno
AND sc.sno=student.sno));
注:以上问题总结参考教材《数据库系统概论》(第五版)王珊 萨师煊 编著。
文章为原创,未经同意,不得转载。若其中存在错误,请联系作者改正,谢谢。