问题:查询至少选修了学生202019122选修的全部课程的学生号码
解题思路:用逻辑蕴含表达这个查询
- 用p表示谓词"学生202019122选修了课程y"
- 用q表示谓词"学生x选修了课程y"
- 则上述查询为(∀y)p → q
等价变换(这一部分会较难理解):
(∀y)p → q ≡ ┐(∃y ( ┐(p → q ) ) ≡ ┐(∃y(┐(┐p Vq))) ≡┐∃y(p∧┐q)
解析:
-
(∀y)p → q :所有的课程y,只要202019122学生选修了课程y,则x也选修了课程y
-
变换后的语义┐∃y(p∧┐q):不存在这样的课程y,学生202019122选修了课程y,而学生x没有选。
SELECT DISTINCT StudentCourseX.Sno
FROM StudentCourse StudentCourseX
WHERE NOT EXISTS(
SELECT *
FROM StudentCourse StudentCourseY
WHERE StudentCourseY.Sno='202019122' AND NOT EXISTS(
SELECT *
FROM StudentCourse StudentCourseZ
WHERE StudentCourseZ.Sno=StudentCourseX.Sno
AND StudentCourseZ.Cno= StudentCourseY.Cno))
- 首先对 StudentCourseX中的第一条记录(202019122),StudentCourseY的第一条记录Sno='202019122’进行判断,结果有数据返回,所以NOT EXISTS的值为假;
- 然后对 StudentCourseY的下一条Sno='202019122’的记录进行判断,直到查询完所有的 StudentCourseY的Sno=‘202019122’,NOT EXISTS的值始终为假,则中间层的WHERE的值为假,最外层的NOT EXISTS的值为真;
- 再对 StudentCourseX中的下一条记录进行查询,直到查询完 StudentCourseX表中所有数据。