关于数据库中NOT IN与where条件的误用迷惑

现有关系数据库如下:
学生(学号,姓名,性别,专业)
课程(课程号,课程名,学分)
学习(学号,课程号,分数)
问:检索没学课程号为“C135”课程的学生信息,包括学号,姓名和专业;

正确答案:
SELECT 学号,姓名,专业 FROM 学生
WHERE 学号 NOT IN

(SELECT 学号 FROM 学习 WHERE 课程号=‘C135’)

我疑惑的是我这种做法有什么问题吗,学艺不精,请大神解答,我也不知道这样对不对,如果错,错在哪里

SELECT 学生.学号,姓名,专业 FROM 学生,学习 WHERE 学生.学号=学习.学号

AND 课程号<>'C135'

数据粒度的问题嘛,你的需求条件是,没有学习C135的学生。C125属于课程,是属于每个学生下一级的属性。但是你的数据存储的是
每个学生对应的每个课程的属性。就相当于,你同一个学生,对应的课程可能有很多;同样的,你同一个课程,对应的学生也有很多,但
是如果是一个学生加上一个课程,那么就可以确定一条数据。这种数据结构,如果你想根据其中一个字段的条件来确定另一列,都得
需要两步。
第一个回答的sql里面用到了exists关键字。这个关键字比较特殊,他后面的子查询返回的是布尔类型。汉字理解的话,应该是‘存在’,
类似于这个意思。把学习了C135的信息查出来,然后exists关键字就发挥作用了,把学号不在查出来的信息里的数据限制出来。
如果没懂可以加VX:daijiubu7878


SELECT 学号,姓名,专业 FROM 学生 WHERE NOT EXISTS 
(SELECT  1 FROM 学习 WHERE 课程号='C135' AND 学生.学号 = 学号)

上面是 学生中 不存在 课程号为 C135 的学生

你的问题是 学习 中不存在 课程号 属性 所以无法直接使用

(SELECT 学号 FROM 学习 WHERE 课程号=‘C135’)

举个例子(筛选出课程号为:C135,且分数高于60分的学生学号,姓名)例子


SELECT 学号,姓名 FROM 学生 WHERE EXISTS 
(SELECT  1 FROM 学习 WHERE 课程号='C135' AND 分数 >=60 AND 学生.学号 = 学号)

SELECT 学生.学号,姓名,专业 FROM 学生,学习 WHERE 学生.学号=学习.学号

AND 课程号<>'C135'
这句sql的问题在于你用两张表关联了,他们是先完成的笛卡儿积,再根据条件得到需要的部分,那么就会出现下面的情况
学号1 姓名1 专业1
学号1 姓名1 专业1
即同样的数据出现多条,原因是如果你查询全部字段,数据本身应该是
学号1 姓名1 专业1 课程号1 分数1
学号1 姓名1 专业1 课程号2 分数2
如果你的sql修改成下面这样,那么结果也是对的
SELECT 学生.学号,姓名,专业 FROM 学生,学习 WHERE 学生.学号=学习.学号

AND 课程号<>'C135' group by 学生.学号,姓名,专业