NOT IN逻辑运算符如何生成此输出?

时间:2012-05-01 16:53:19

标签: mysql sql

我有以下表格和数据:Screenshot of the data here

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;

我认为Oracle会生成此输出。

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

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

3 个答案:

答案 0 :(得分:3)

它会返回成绩低于B的学生。

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

用语言说:

  

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

的学生

答案 1 :(得分: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以获取学生信息(也可以CLASSCOURSE如果需要,课程名称。)

答案 2 :(得分: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