1

下周我有一个关于数据库的大学实习。我需要围绕一所大学的计划创建 15 个查询,如下所示:

  • 学生(学生编号、名字、姓氏、性别、出生日期、地址、级别、学位代码)
  • 学位(Degree_Code,Degree_Name,School_Name)
  • 模块(Module_Code、Module_Title、School_Name)
  • 学校(School_Name,教师,校长)
  • Take_Exam(Student_No, Module_Code, Mark)

我已经完成了 14 个查询,但我被困在这个查询上:

  • 检索参加每个模块的学生的姓名。(提示。使用不存在)。

我一直在阅读不存在的查询,但我什至不知道从哪里开始!我创建了这段代码:

select students.student_no, fname, lname, count(module_code)
from students left join take_exam using (student_no)
group by student_no
having count(module_code) < 19
order by lname;

这将返回所有未参加所有 19 个模块的学生。但是,我讨厌代码,因为它涉及 < 19,这意味着如果以后模块的数量发生了变化,则该值将需要更改,这是低效的。

谁能指出我正确的方向并给我一些关于使用“不存在”查询的指导?

谢谢,安德鲁

4

3 回答 3

1

使用not exists

select *
from Student s1 
where not exists 
         (select 1 
          from Module 
          where Module_Code not in
                      (select Module_Code 
                       from Take_Exam 
                       where Student_No = s1.Student_No)

解释 :

s对于表中的每个学生Student,我们将添加s到结果中,如果:不存在表中的任何模块,Module因此该模块未映射到s表中的学生Take_Exam

它并不直观,但它与:“所有参加每个模块的学生”完全一样

于 2012-10-28T16:24:54.920 回答
1

在没有完全回答你的作业的情况下,这里有一个提示可能会有所帮助:

试着从另一个角度看它。回答了所有模块问题的学生不会有任何与模块表左连接的空字段,对吗?

此外,您可能不需要左外连接table_exam... 因为您只需要参加考试的学生。

于 2012-10-28T16:15:47.493 回答
0

我认为,您可以获取distinct count of modules from module table然后使用它进行比较,例如:

     select students.student_no, fname, lname, count(t.module_code)
     from module m, students join take_exam t using (student_no)
     group by student_no
     having count(t.module_code) = count(distinct(m.module_code)) 
     order by lname;

请注意:我将条件更改为=并加入,inner join因为您希望学生学习所有模块。

编辑:使用 notExit:

     select students.student_no, fname, lname 
     from students 
     WHERE  NOT EXISTS (select *
                from module m, students join take_exam t using (student_no)
                group by student_no
                having count(t.module_code) < count(distinct(m.module_code)) 
                group by student_no
             )
     order by lname;
于 2012-10-28T16:16:47.677 回答