sql不存在和子查询

时间:2012-01-18 07:13:13

标签: sql exists

假设有一个大学数据库

name     |  state | enrollment
=============================
Stanford | CA     | 15000
-----------------------------
Berkley  | CA     | 36000
-----------------------------
MIT      | MA     | 10000
-----------------------------
Cornell  | NY     | 21000

不使用max(),我可以使用exists运算符和子查询来获得最大注册量的大学

select name from college c1 where not exists ( select * from college c2 where c2.enrollment > c1.enrollment);

返回

 Berkeley
(1 row)

按预期

但是,我无法理解查询是如何工作的。如果子查询返回至少一个记录,则满足exists条件。因此,在上面,仅当子查询返回空集时才会满足not exists。或者我认为..

为了检查这一点,我尝试运行子查询

select c2.name from college c2,college c1 where c2.enrollment > c1.enrollment);

但是这会返回

  name   
----------
 Stanford
 Berkeley
 Berkeley
 Berkeley
 Cornell
 Cornell
(6 rows)

我真的很困惑。有人可以澄清第一个查询是如何工作的以及为什么我在这里错了?

5 个答案:

答案 0 :(得分:3)

select name from college c1 where not exists ( select * from college c2 where 
c2.enrollment > c1.enrollment);

以上查询查找可以找到注册值>的记录。外部查询的当前行。

假设查询以自上而下的顺序运行,它将

  1. 看看斯坦福大学招生&检查是否有其他行 注册>斯坦福大学招生。子查询将返回2 记录(康奈尔和伯克利)。所以,它不会匹配。
  2. 看看伯克利的招生&检查是否有其他行有注册>伯克利报名。子查询将返回0条记录。因此,NOT EXISTS条件将为伯克利返回。

答案 1 :(得分:2)

这是相当简单的 - 查询说'找到我没有任何其他高校招生的大学'

(注意:如果你有联系,这显然会返回多个结果)

您的查询是:“找到任何大学,其入学率高于其他大学”,因此每一行都将被退回,但入学率最低的一行(它也将排除最低级别的任何关系)

答案 2 :(得分:1)

在jour交叉连接并应用WHERE表达式之后,有时c1中有一行来自c1的一行。实际上,你在两个查询中做了很多不同的事情。

答案 3 :(得分:1)

Exists只是测试内部查询是否返回任何行。如果是,则外部查询继续。如果不是,则外部查询不会执行,并且整个SQL语句不返回任何内容。

EXISTS的语法是:

    SELECT "column_name1" FROM "table_name1" WHERE EXISTS(SELECT * FROM "table_name2"
    WHERE [Condition])

由于子查询返回的行数超过0,因此EXISTS条件为true,并且放置在内部查询中的条件不会影响外部查询的运行方式。

答案 4 :(得分:0)

名称

斯坦福  伯克利  伯克利  伯克利  康奈尔  康奈尔

返回,因为比较顺序如下:

斯坦福大学| CA | 15000

伯克利| CA | 36000

MIT | MA | 10000

康奈尔|纽约| 21000

第一个C2将是stanford,C1将是所有大学一个接一个 斯坦福并不比自己大, 斯坦福并不比伯克利大, 斯坦福大于麻省理工学院, 斯坦福并不比康奈尔大 - 这结束了第一个循环给出一个斯坦福

再次在第二种情况下,c2将是berkely,而C1将是所有大学的顶级 得到3个伯克利 和第三种情况没什么 第4例单康奈尔

多数民众赞成