EXISTS如何返回除所有行或没有行之外的其他内容?

时间:2014-11-18 08:29:34

标签: sql sql-server

我是SQL程序员的开始 - 我得到的东西很多,但不是EXISTS。

在我看来,通过文档看,整个EXISTS语句返回一个布尔值。

但是,我看到了可以使用它的具体示例,并返回表的一部分,而不是全部或不返回。

SELECT DISTINCT PNAME
FROM P    
WHERE EXISTS
(
    SELECT *
    FROM SP Join S ON SP.SNO = S.SNO
    WHERE SP.PNO = P.PNO
    AND S.STATUS > 25
)

此查询返回一个值,即符合条件的值(S.Status> 25)。

然而,对于其他查询,如果EXISTS子查询中的一行甚至是真的,它似乎返回我正在选择的整个表。

如何控制这个?

4 个答案:

答案 0 :(得分:3)

您实际上已创建了Correlated subqueryExists谓词接受子查询作为输入,如果子查询返回任何行,则返回TRUE,否则返回FALSE。

对表P的外部查询没有任何过滤器,因此将考虑此表中的所有行,EXISTS谓词返回TRUE。

SELECT DISTINCT PNAME -- Outer Query
FROM P

现在,如果表EXISTS中的当前行在TRUE中的相关行P

SP Join S ON SP.SNO = S.SNO谓词将返回S.STATUS > 25
SELECT *
FROM SP Join S ON SP.SNO = S.SNO
WHERE SP.PNO = P.PNO -- Inner query
AND S.STATUS > 25

使用EXISTS谓词的一个好处是,它允许您直观地将英语称为查询。例如,可以像普通英语中那样读取此查询:从表unique PNAME中选择所有P,其中至少存在一行PNO等于PNO在表格SP和Status in table S > 25中,提供的表格SPS基于SNO加入。

答案 1 :(得分:3)

EXISTS等子查询可以是相关的,也可以是非相关的。

在您的示例中,您使用相关子查询,这通常是EXISTS的情况。您在SP中查找给定P.PNO的记录,即您对每个P记录进行查找。

如果没有SP.PNO = P.PNO,您将拥有一个不相关的子查询。即子查询不再依赖于P记录。它会为任何P记录返回相同的结果(状态> 25根本不存在)。大多数情况下,当发生这种情况时,这是错误地完成的(一个忘记将子查询与相关记录联系起来),但有时也是如此。

答案 2 :(得分:3)

您使用的是哪种SQL语言?

EXISTS返回allways true或false或者它总是返回行,但是在WHERE EXISTS中...它将检查返回的行> 0(=> true)。

Oracle,MySQL,PostreSQL:

  

EXISTS条件与子查询结合使用,并且被认为是满足"如果子查询返回至少一行。   (http://www.techonthenet.com

答案 3 :(得分:2)

你在主查询的where子句中的条件

  

从P

中选择DISTINCT PNAME

依赖于存在, 如果您的子查询返回任何行, 然后exists返回true,否则返回false 如果Exists返回true,则主查询where子句返回p中的所有记录,如果返回false则返回false