我有以下表和数据:
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
操作符如何在上面的查询中生成输出?
发布于 2012-05-01 09:06:00
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-01 08:55:33
它返回成绩比B
差的学生。
NOT IN
过滤掉了你在那之后定义的内容。
用词:
选择所有学生,但不选择成绩为
A
或B
的学生
发布于 2012-05-01 09:03:59
子查询(SELECT SID FROM CLASS_STUDENT WHERE GRADE IN ( 'A' , 'B' ))
在至少一个班级中选择所有成绩为A或B的学生的SID。当与IN
运算符一起使用时,列表将隐式地重复。从您的数据中可以看出,学生1、2和4在至少一个类中都有A或B,因此将包括在该子查询的结果集中。
然后,完整的查询只是从STUDENT
中选择不包含在子查询返回的列表中的所有行。所以我认为你得到了两排,小岛屿发展中国家3和5。
你的“预期结果”没什么意义。当您的查询选择所有学生,然后筛选出一些行时,没有理由期望同一个学生有多个行。
您的查询所做的是显示在至少一个班级中没有A或B级的学生。我怀疑你想要的是向每个学生展示分数比B差的班级组合(这似乎与你的预期结果相一致)。要做到这一点,我建议将查询从CLASS_STUDENT
表中删除,并加入STUDENT
获取学生信息(如果需要,还可以向CLASS
和COURSE
获取课程名称)。
https://stackoverflow.com/questions/10401189
复制