数据库系统工程师 · 高频练习

SQL 怎么查询选修了全部必修课的学生?

中级 单选题 第 932 题 困难 数据库系统工程师SQL关系除法NOT EXISTS全称量词
题目

有学生表 Student(sid)、必修课表 RequiredCourse(cid) 和选课表 Enroll(sid,cid)。要查询‘选修了全部必修课的学生’,下列条件最准确的是()。

A 存在一门必修课,被该学生选修
B 不存在一门必修课,使得该学生没有选修它
C 该学生的选课总数等于全部课程表的记录数
D 该学生至少选修两门课程
题目类型:原创高难度练习题 用途:用于帮助理解数据库系统工程师相关考点和答案解析,不等同于官方真题。
正确答案
B
答案解析

‘对所有必修课都已选’可改写为‘不存在任何一门必修课未被该学生选修’。SQL常用双重NOT EXISTS:外层检查是否存在缺失的必修课,内层检查该学生是否有对应选课记录;外层NOT EXISTS保证这种缺口不存在。

选项分析

A

错误。它只证明至少选过一门必修课,是存在量词,不是全部。

B

正确。‘不存在未选的必修课’与‘选修全部必修课’逻辑等价。

C

错误。全部课程表可能包含选修课,选课表还可能重复或包含额外课程,简单比较总数口径不可靠。

D

错误。选课数量达到两门不能证明覆盖了必修课集合。

本题为什么容易错

这类题难在中文里的‘全部’。只要SQL里出现一次EXISTS,往往只能表达至少一个;全称条件通常要寻找反例,再用外层NOT EXISTS否定反例存在。

先看结论

简短答案

SQL 怎么查询选修了全部必修课的学生,正确答案是 B(不存在一门必修课,使得该学生没有选修它)。‘对所有必修课都已选’可改写为‘不存在任何一门必修课未被该学生选修’。SQL常用双重NOT EXISTS:外层检查是否存在缺失的必修课,内层检查该学生是否有对应选课记录;外层NOT EXISTS保证这种缺口不存在。

解析

易混淆概念对比表

概念本题判断区别要点记忆提示
存在一门必修课,被该学生选修 本题干扰项 错误。它只证明至少选过一门必修课,是存在量词,不是全部。 看到该词不要急着选,先判断是否真正解决题干问题
不存在一门必修课,使得该学生没有选修它 本题正确答案 正确。‘不存在未选的必修课’与‘选修全部必修课’逻辑等价。 看到题干核心场景时优先联想到它
该学生的选课总数等于全部课程表的记录数 本题干扰项 错误。全部课程表可能包含选修课,选课表还可能重复或包含额外课程,简单比较总数口径不可靠。 看到该词不要急着选,先判断是否真正解决题干问题
该学生至少选修两门课程 本题干扰项 错误。选课数量达到两门不能证明覆盖了必修课集合。 看到该词不要急着选,先判断是否真正解决题干问题
本题易混淆选项怎么区分
  • 存在一门必修课,被该学生选修:错误。它只证明至少选过一门必修课,是存在量词,不是全部。
  • 该学生的选课总数等于全部课程表的记录数:错误。全部课程表可能包含选修课,选课表还可能重复或包含额外课程,简单比较总数口径不可靠。
  • 该学生至少选修两门课程:错误。选课数量达到两门不能证明覆盖了必修课集合。
复习

知识点详解

关系除法常用于回答‘哪些X与集合Y中的每个元素都建立了关系’。在SQL中,可以用双重NOT EXISTS表达:对某个学生,不存在一门必修课,使得选课表中不存在该学生与该课程的对应记录。另一种常见写法是把选课表限制到必修课集合后分组,再比较COUNT(DISTINCT cid)与必修课总数。双重NOT EXISTS更直接体现逻辑,但要理解空集合时全称命题为真的边界。

备考速记

查询全部,不数有多少;先找漏掉的,再要求一个都找不到。

SQL 在全称量词场景中的作用

SQL在本题中的核心价值,是解决“有学生表 Student(sid)、必修课表 RequiredCourse(cid) 和选课表 Enroll(sid,cid)。要查询‘选修了全部必修课的学生’,下列条件最准确的是()”这个场景问题。复习时不要只背选项名称,还要理解它为什么适用于该场景,以及它能解决哪类安全、流程或管理问题。

拓展

同类题怎么考

  • 查询选修全部必修课的学生。
  • 查询供应全部指定零件的供应商。
  • 比较双重NOT EXISTS与GROUP BY/HAVING计数写法。
SQL 在数据库系统工程师软考中的考法

软考选择题通常不会只考概念定义,还会把SQL放到全称量词场景中,要求判断它的作用、适用范围或与相近概念的区别。遇到这类题时,先抓住题干中的业务场景,再看哪个选项最能解决该场景下的核心问题。

解题思路

老师通常把这句话倒过来说:不是证明学生选了很多课,而是去找一门他漏掉的必修课。如果一门都找不到,才说明全部选完。对应SQL骨架就是 `NOT EXISTS (必修课 r WHERE NOT EXISTS (该生选课 e))`,所以选B。

考点定位

SQL没有直接的FOR ALL语法时,常把全称条件改写成‘不存在反例’。看到‘全部、每一个、所有’要警惕双重NOT EXISTS或分组计数。

易错提醒

  • 把至少选过一门必修课当成选完所有必修课。
  • COUNT时没有按必修课集合过滤,也没有处理重复选课记录。
  • 忽略必修课表为空时的空真语义:按双重NOT EXISTS,所有学生都满足没有漏课。

备考提示

  • 先把‘全部P都满足Q’翻译成‘不存在P使Q不成立’,再写SQL。
  • 分组计数写法要用COUNT(DISTINCT cid),并确保分母是必修课数量。

你可能还想了解

  • 双重NOT EXISTS为什么能表示全部?
  • 选修全部课程怎样用GROUP BY写?
  • 关系除法适合哪些SQL场景?
  • 必修课表为空时查询会返回什么?

本文小结

‘选修全部必修课’等价于‘不存在一门尚未选修的必修课’。双重NOT EXISTS正是把全称量词改写成不存在反例。