SQL与Any对!= Any

时间:2019-03-16 02:13:01

标签: sql

我有下表:

学生:

+------+---------+
| Snum |  Sname  |
+------+---------+
| S1   | Charles |
| S2   | Amy     |
| S3   | John    |
+------+---------+

课程:

+-----+------------+
| cid | coursecode |
+-----+------------+
| C1  | CMPT222    |
| C2  | ASC111     |
+-----+------------+

注册:

+------+-----+
| sid  | cid |
+------+-----+
| S1   | C1  |
| S2   | C2  |
+------+-----+

一般来说,我有3个学生,其中2个已经注册。
查询为:查找未注册的数字:

SELECT DISTINCT S.snum
FROM Student S
WHERE S.snum! = any (SELECT E.snum FROM Enrolled E )

此查询返回:

1
2
3

错了。

我的理解是:对于外部查询中的每个元组,ANY将检查是否存在至少一个元组。如果是,则返回TRUE。如果我们使用!=,那么它应该返回3。

我想念什么?

2 个答案:

答案 0 :(得分:0)

这是您的查询:

SELECT DISTINCT S.snum
FROM Student S
WHERE S.snum <> any (SELECT E.snum FROM Enrolled E )

基本上,如果子查询返回多个值,则条件将始终为true。为什么?好吧,考虑返回的集合是否为12。好吧,如果将值与其中之一进行比较,则条件始终为真。请记住:1 <> 2。因此,如果该值与第一个匹配,则第二个不匹配。

有简单的方法可以解决此问题。例如:

WHERE NOT (S.snum = any (SELECT E.snum FROM Enrolled E ))

或者:

WHERE S.snum NOT IN (SELECT E.snum FROM Enrolled E )

实际上,我不喜欢NOT IN,因为它对待NULL值的方式有所不同。在这种情况下,我更喜欢NOT EXISTS

答案 1 :(得分:0)

因为您要评估的谓词始终为真,所以= any()至少有一个等价项。不等于或<> any()至少等于一个。由于子查询返回的集合,最后一个谓词始终为true,而前一个谓词仅为s1s2值。

请注意,如果子查询仅返回一个值,则结果选择将有所不同。

详细解释

您的子查询返回以下值:s1s2。然后,您的rdbms逐行评估谓词。然后,

s1 <> s1-> false

s1 <> s2-> true

谓词评估,true因为any()

下一个值

s2 <> s1-> true

谓词评估true ...第三个值:

s3 <> s1-> true

请注意,some()any()是等效的子句。

any()视为or门。每次找到一个“真”(输入),输出就是“真”。