说明
需要基本的数理逻辑知识和数据库知识
题目
(以学生-课程数据库为例)(例子选自《数据库系统概论》(第五版))
Student表
学号 Sno | 姓名 Sname | 性别 Ssex | 年龄 Sage | 所在系 Sdept |
---|---|---|---|---|
201215121 | 李勇 | 男 | 20 | CS |
201215122 | 刘晨 | 女 | 19 | CS |
201215123 | 王敏 | 女 | 18 | MA |
201215125 | 张立 | 男 | 19 | IS |
Course表
课程号 Cno | 课程名 Cname | 先行课 Cpno | 学分 Ccredit |
---|---|---|---|
1 | 数据库 | 5 | 4 |
2 | 数学 | 2 | |
3 | 信息系统 | 1 | 4 |
4 | 操作系统 | 6 | 3 |
5 | 数据结构 | 7 | 4 |
6 | 数据处理 | 2 | |
7 | PASCAL语言 | 6 | 4 |
SC表
学号 Sno | 课程名 Cno | 成绩 Grade |
---|---|---|
201215121 | 1 | 92 |
201215121 | 2 | 85 |
201215121 | 3 | 88 |
201215122 | 2 | 90 |
201215122 | 3 | 80 |
问:查询至少选修了学生201215122选修的90分以上(含90分)全部课程的学生名字?
解题思路
(1) 明确最终目标——学生姓名(Sname——位于Student表)
(2) 学生的分数位于SC表,该题不需要用到Course表
(3) 一种可行的思路是:该题只涉及两个表——SC和Student,SC用于记录选课记录,一个学生通常有多条选课记录,也就是说,Student表的记录实际问题中应该比SC表中少很多。因此我们可以对Student表一条一条浏览,判断该记录是不是符合题目条件的学生。
(4) 我们对该题进行“中文翻译”:对任意一个Student表的学生X,对SC任意一条选课记录Y,如果这门课学生201215122选了,并且学生20121512该门课的成绩大于等于90分,那么就有 学生X选了Y中的那门课。
(5) 数理逻辑表示:
∀
x
∈
S
t
u
d
e
n
t
,
∀
y
∈
S
C
,
(
p
∧
q
)
→
r
p
:
学
生
201215122
选
了
y
.
C
n
o
q
:
学
生
201215122
该
课
成
绩
y
.
G
r
a
d
e
≥
90
r
:
x
选
了
该
门
课
y
.
C
n
o
\forall x\in Student,~\forall y\in SC,~(p\wedge q)\to r\\ p:学生201215122选了 y.Cno \\q:学生201215122该课成绩 y.Grade\ge 90 \\r: x选了该门课y.Cno
∀x∈Student, ∀y∈SC, (p∧q)→rp:学生201215122选了y.Cnoq:学生201215122该课成绩y.Grade≥90r:x选了该门课y.Cno
注:(4)中的那么就有在数理逻辑中体现为 蕴含“
→
\to
→”
∀
x
∀
y
(
(
p
∧
q
)
→
r
)
\forall x\forall y((p\wedge q)\to r)
∀x∀y((p∧q)→r)
但是,在sql语句中并没有任意,只有存在,需要对我们的表达式进行改写
∀
x
:
┐
∃
y
┐
(
┐
(
p
∧
q
)
∨
r
)
∀
x
:
┐
∃
y
(
p
∧
q
∧
┐
r
)
\forall x:\urcorner\exist y\urcorner(\urcorner(p\wedge q)\vee r) \\ \forall x:\urcorner\exist y(p\wedge q\wedge\urcorner r)
∀x:┐∃y┐(┐(p∧q)∨r)∀x:┐∃y(p∧q∧┐r)
SELECT Sname
FROM Student X
WHERE NOT EXISTS(
SELECT *
FROM SC Y
WHERE Y.Sno=201215122 AND Y.Grade>=90 AND NOT EXISTS(
SELECT *
FROM SC Z
WHERE X.Sno=Z.Sno AND Z.Cno=Y.Cno
)
);