使用关系代数查找选考学生A考试真子集的学生
如何查找选考考试是学生A所考考试真子集的学生?
咱们一步步来解决这个问题,核心是找出那些学生的考试集合是A的真子集——也就是他们考的每一门A都考了,而且A至少有一门他们没考。先把你的示例数据整理成清晰的表格:
| student | exam |
|---|---|
| A | 1 |
| A | 2 |
| B | 1 |
| B | 3 |
| C | 1 |
| C | 2 |
| D | 1 |
你的初始思路里第三步没法区分“考试是子集但数量更少”和“考试包含A没考的科目”这两种情况,咱们调整一下步骤,用标准关系代数精准实现(参考《Fundamentals of Database Systems》(Elmasri, Navathe)第239页的定义):
步骤1:获取学生A的所有考试集合
首先提取出A考过的全部考试:
examsA ← π exam (σ student='A' (Exams))
示例里这一步得到的集合是 {1,2}。
步骤2:筛选出所有考试都是A的子集的学生
首先要排除那些考了A没考过的科目的学生,咱们用笛卡尔积和差集来实现:
# 生成所有学生与A的考试的笛卡尔积(所有学生理论上可以考的A的科目) allStudentExamsA ← π student (Exams) × examsA # 找出学生实际考试中不在A的考试集合里的记录(比如B考的3) invalidExamRecords ← Exams - allStudentExamsA # 提取这些不符合子集要求的学生(示例里的B) badStudents ← π student (invalidExamRecords) # 剩下的就是所有考试都属于A的考试集合的学生(A、C、D) subsetStudents ← π student (Exams) - badStudents
步骤3:排除和A考试完全相同的学生
接下来要去掉那些和A考的科目完全一致的学生(也就是考试集合等于A的,比如示例里的A和C),这里用关系除法:
# 除法操作会返回选考了examsA所有科目的学生 exactMatchStudents ← Exams ÷ examsA
步骤4:得到最终的真子集学生
从subsetStudents里减去exactMatchStudents,剩下的就是我们要的结果:
result ← subsetStudents - exactMatchStudents
示例里最终结果就是 {D},完全符合预期。
内容的提问来源于stack exchange,提问作者Kevin Spaghetti
相关产品推荐
相关产品推荐

