0

我有以下表格和数据:此处数据的屏幕截图

course:
course#     ctitle               units
---------   -------------------  -----
ACCT 201    Financial Account      3
CHEM 356    Organic Chemistry      4
HIST 101    US History             5
MINS 235    Database Design        4
MINS 301    Intro to Business IS   3
MINS 350    Systems Analysis       4
PHED 434    Advanced Gym           2

class:
class#  course#      sec#   semyr
------  ----------   -----  -----
203     ACCT 201       03    F11
204     ACCT 201       04    F11
307     MINS 301       07    F11
418     MINS 235       04    F11
438     MINS 350       01    F11
624     PHED 434       02    F11

student:
sid  sname       major
---  ----------  ----------
 1    Bob        MINS
 2    Mary       POMG
 3    Joe        MGMT
 4    Sue        MKTG
 5    Jim        ACCT

class_student:
class  sid   grade
-----  ----  -----
 203     2     B
 203     5     D
 204     1     C
 204     4     C
 307     1     B
 307     2     B
 307     4     A
 418     1     A
 418     2     B
 418     5     C
 438     1     B
 438     4     C
 634     5     F

grade:
grade  grade_pts
-----  ---------
  A        4
  B        3
  C        2
  D        1
  F        0

当我运行以下查询时:

SELECT      *  
FROM        STUDENT 
WHERE       SID NOT IN 
            (   SELECT  SID 
                FROM    CLASS_STUDENT 
                WHERE   GRADE IN ('A' , 'B')
            ) 
ORDER BY    SID;

我认为甲骨文会产生这个输出。

sid sname major
--- ----- -----
 1  bob   mins
 4  sue   mktg
 5  jim   acct
 5  jim   acct
 5  jim   acct

我想了解 NOT IN 逻辑运算符的工作原理。运算符如何NOT IN在上述查询中工作以生成输出?

4

3 回答 3

3

它返回成绩低于B.

NOT IN过滤掉你之后定义的内容。

用一句话来说:

选择所有学生,但不选择有成绩的学生AB

于 2012-05-01T16:55:33.017 回答
1

子查询(SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' ))选择至少在一个班级中成绩为 A 或 B 的所有学生的 SID。与IN运算符一起使用时,列表会被隐式删除重复数据。在您的数据中显示,学生 1、2 和 4 在至少一个班级中都有 A 或 B,因此将包含在此子查询的结果集中。

然后,完整查询只是从中选择STUDENT不包含在子查询返回的列表中的所有行。所以我认为你得到了两行,SID 为 3 和 5。

您的“预期结果”毫无意义。当您的查询选择所有学生然后过滤掉一些学生时,没有理由期望同一个学生有多个行。

您的查询正在执行的是显示至少在一个班级中没有 A 或 B 成绩的学生。我怀疑您想要的是显示每个学生班级组合的成绩比 B 差(这似乎与您的预期结果一致)。为此,我建议将查询从CLASS_STUDENT表中移开,并加入以STUDENT获取学生信息(如果需要,可能还CLASS可以COURSE获取课程名称)。

于 2012-05-01T17:03:59.273 回答
1
SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' )

将选择具有 A、B 成绩的学生的 sid。将产生一个 sid 列表

SID
2
1
2
4
1
2
1

然后

SELECT  *  FROM STUDENT 
WHERE   SID NOT IN  ...

将导致:

SID     sname       Major
3       joe         mgmt
5       jim         acct
于 2012-05-01T17:06:00.047 回答