选择另一个表中缺少的记录的有效方法

时间:2013-06-29 12:28:26

标签: sql database join

我有3张桌子。以下是结构:

  • studentid int, name varchar(20)
  • coursecourse_id int, subject varchar(10)
  • student_coursest_id int, course_id int) - >包含注册课程的学生姓名

现在,我想写一个查询,找出没有参加任何课程的学生。我可以想象有多种方法可以获取这些信息。能不能让我知道哪一个是最有效的,也是,为什么。此外,如果还有其他更好的执行方式,请告诉我。

db2 => select distinct name from student inner join student_course on id not in (select st_id from student_course)

db2 => select name from student minus (select name from student inner join student_course on id=st_id)

db2 => select name from student where id not in (select st_id from student_course)

提前致谢!!

4 个答案:

答案 0 :(得分:9)

您使用的子查询,无论是not inminus还是其他,通常效率低下。执行此操作的常用方法是left join

select name 
from student 
left join student_course on id = st_id
where st_id is NULL

使用join是“正常”和优先解决方案。

答案 1 :(得分:1)

使用NOT EXISTS的规范(甚至可能是概要)成语(恕我直言):

SELECT *
FROM student st
WHERE NOT EXISTS (
  SELECT *
  FROM student_course
  WHERE st.id = nx.st_id
  );

优点:

  • NOT EXISTS(...)已经很老了,大多数优化工作者都知道如何处理它
  • ,因此它可能会出现在所有平台上
  • nx.相关名称​​泄露到外部查询中:外部查询中的select *只会从student表中生成字段,并且而不是student_course表中的(null)行,就像在LEFT JOIN ... WHERE ... IS NULL情况下一样。这在具有大量范围表条目的查询中特别有用。
  • (NOT) IN容易出错(NULL),并且在某些实现上可能会执行错误(必须从不相关子查询的结果中删除重复项和NULL)

答案 2 :(得分:0)

使用“not in”通常很慢。这使您的第二个查询最有效。你可能不需要括号。

答案 3 :(得分:0)

正如评论:我建议选择学生ID(这是唯一的),而不是名称。

作为另一个查询选项,您可能希望加入两个表,按student_id分组,count(course_id)具有count(course_id)= 0.

另外,我同意索引会更重要。

相关问题