这几天数据库上机,关于全称量词的某道题想了很久才明白一些,写下这篇博客做下巩固。
说明
SQL中没有全程量词,但是可以将其转化为等价的带有存在量词的语句,即可以用exists
代替全称量词。
转化公式
数学描述
$(\forall x)P=\neg (\exists x(\neg P) )$
自然语言描述
对于所有$x$ ,$P$ 成立 等价于 存在$x$ 使$P$ 不成立的情况不存在。
举个栗子
上面的没看懂没关系,来看一个教科书上的例子。
查询至少选修了学号为03051066选修的全部课程的学生学号。
数学语言描述
- $x$ 表示学号为$03051066$ 选修了课程$cno$
- $P$ 表示学生$sno$ 也选修了课程$cno $
则有,$(\forall x)P=\neg (\exists x(\neg P) )$ 。
自然语言描述
有上述数学描述可得,存在学号为$03051066$ 选修了课程$cno$ 而学生$sno$ 没有选修课程$cno $ 的情况不存在。
换句话来说,也就是:
从$sc$ 中筛选出的每个学号$Number$,不存在这样的课程
- 学号为$03051066$ 的选修过
- 学号为$Number$ 的人未选修
C/C++语言描述
set<sno>select;
for(int i=0;i<sc.size();++i){
bool flag=1;
for(int j=0;j<sc.size();++j){
if(sc[j].sno=='03051066'){
bool galf=1;
for(int k=0;k<sc.size();++k){
if(sc[i].sno==sc[k].sno&&sc[j].cno==sc[k].cno){
galf=0;
break;
}
}
if(galf){
flag=0;
break;
}
}
}
select.insert(sc[i].sno);
}
Python语言描述
def exists_3(Number, course):
for z in sc:
if z.sno == Number and z.cno == course:
return False
return True
def exists_2(Number):
for y in sc:
if y.sno == '03051066' and exists_3(Number, y.course) == True:
return False
return True
select = set()
for x in sc:
if exists_2(x.sno) == False:
select.add(x.sno)
SQL语言描述
select sno,sname
from student
where sno in (
select sno
from sc scx
where not exists(
select *
from sc scy
where scy.sno='03051066' and not exists(
select *
from sc scz
where scz.sno=scx.sno and scz.cno=scy.cno
)
)
);