SQL问题:告诉我没有参加过某一课程的学生?

时间:2010-07-08 15:07:19

标签: sql ms-access

所以我有这些表:

学生: 学生证 - 名字 - 姓氏 - 电子邮件

课程: 目录ID - 课程名称 - 说明

条款: 术语ID - 开始日期 - 结束日期

COURSEINSTANCES: CourseInstance ID - 目录ID - 术语ID

STUDENTCOURSES: StudentCourse ID - CourseInstance ID - 学生ID - 添加到数据库的日期

这样可以很容易地看出哪些学生参加过哪些课程。我不知道该怎么去找出哪些学生没有参加过某一课程。

做这样的事情:

WHERE ((CourseInstances.CatalogLookup)<>504)

只会给我一份学生所选课程的列表,这些课程不等于目录编号504,如下所示:

塔拉 - 501

Tara - 502

Tara - 505

约翰 - 503

所以我举了504个。所以我不希望我出现在这个名单上。上面的SQL只显示我不是504的所有课程,但它不会将我从列表中排除。

有什么想法吗?这可能吗?

6 个答案:

答案 0 :(得分:7)

我更喜欢这种语法而不是外连接,IMO更容易阅读:

select * 
from STUDENTS 
where StudentID not in 
(
    select StudentID 
    from STUDENTCOURSES s 
    inner join COURSEINSTANCES c on s.CourseInstanceID  = c.CourseInstanceID 
    where c.CatalogID = 504
)

在嵌套查询中,您选择已参加课程504的所有学生的学生ID。

然后,您选择所有学生ID未包含在嵌套查询中的学生。

修改
正如ChrisJ已经说过的那样,c和s是表名的别名 没有它们,查询将如下所示:

select * 
from STUDENTS 
where StudentID not in 
(
    select StudentID 
    from STUDENTCOURSES 
    inner join COURSEINSTANCES on STUDENTCOURSES.CourseInstanceID = COURSEINSTANCES.CourseInstanceID 
    where CatalogID = 504
)

我总是使用别名,因为:
a)我太懒了,不必经常输入表名 b)在我看来,它更容易阅读,特别是当您连接具有长名称的表时。

答案 1 :(得分:2)

您应该阅读outer joins

答案 2 :(得分:2)

尝试这样的事情:

SELECT * 
FROM Users 
WHERE UserID NOT IN
( SELECT UserID
  FROM 
    Users
  INNER JOIN
    ClassesTaken ON Users.UserID = ClassesTaken.UserID AND ClassesTaken.ClassNumber = 504)

前几天我想到了另一种方式:

SELECT * 
FROM 
Users
LEFT OUTER JOIN ClassesTaken ON Users.UserID = ClassesTaken.UserID AND ClassesTaken.ClassNumber = 504
WHERE ClassesTaken.UserID IS NULL

答案 3 :(得分:1)

Access中的三种主要方式

  • NOT IN(如果在子查询中出现任何NULL,请小心排除任何NULL)
  • OUTER JOIN并过滤NULL(可能需要添加DISTINCT)
  • NOT EXISTS

其他RDBMS也有EXCEPTMINUS

答案 4 :(得分:1)

SELECT * FROM students 
WHERE studentId not in 
(SELECT distinct studentID FROM studentCourses WHERE courseInstanceID = 504)

答案 5 :(得分:-1)

功课?使用集合运算符。

选择所有学生MINUS选择参加此课程的学生...