【问题标题】:MYSQL query involving 'not exists'MYSQL 查询涉及“不存在”
【发布时间】:2012-10-18 02:42:37
【问题描述】:

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

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

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

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

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

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 个模块的学生。但是,我讨厌代码,因为它涉及到

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

谢谢,安德鲁

【问题讨论】:

  • 提示:你需要第二个不存在。 (没有他/她没有服用过的mudule)
  • @wildplasser:老实说,这就是我所担心的!从来没有用过一个,更不用说两个了。谢谢你的建议。
  • 一旦你完成了,这一切似乎都是微不足道的。 NOT EXISTS 非常接近自然语言/逻辑。

标签: mysql sql not-exists


【解决方案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)

解释:

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

这并不直观,但与以下内容完全相同: "所有参加每个模块的学生"

【讨论】:

  • 我能问一下“1”在您的第一个嵌套查询中的作用吗?
  • not exists 检查查询结果是否不为空 - 所以选择什么都没关系,1*..
  • 您的代码运行良好,但我在处理语法时遇到了一些困难。你介意解释一下 MYSQL 在这个查询中的工作顺序以及每个步骤的作用吗?非常感谢。
  • @AndrewMartin - 我已经添加了一些解释,希望对您有所帮助。
【解决方案2】:

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

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

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

【讨论】:

  • 感谢你们俩的建议 - 我会尝试重新编写代码!
【解决方案3】:

我认为,您可以获取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;

【讨论】:

  • 感谢您的回答 - 但是,我认为我必须使用 NOT EXISTS 查询(即使这不是最简单的方法)。此外,您的代码不喜欢有 count(module_code) - 它说这是模棱两可的。
  • @AndrewMartin:在count(module_code) 中添加了一个限定符t. 作为count(t.module_code)。更新了查询。请检查。
  • @AndrewMartin:如果您觉得有帮助,请不要忘记采纳答案。谢谢!
  • 我确实想接受答案,我发现您使用的逻辑更容易,但我认为我必须使用不存在的查询:(
  • @AndrewMartin:用not exists添加了一个答案。
猜你喜欢
  • 1970-01-01
  • 2016-07-26
  • 2023-04-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
相关资源
最近更新 更多