Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.
子查询比较测试中使用的子查询和集合成员资格测试中使用的子查询都返回子查询表中的数据值。不过,有时候您可能更关心子查询是否返回一些 结果,而不是返回哪些 结果。存在测试 (EXISTS) 就是用来检查子查询是否生成一些查询结果行的。如果子查询生成一行或多行结果,则 EXISTS 测试就返回 TRUE。否则,它会返回 FALSE。
下面的示例是一个使用子查询表示的请求:"哪些客户在 2001 年 7 月 13 日以后下了订单?"
SELECT GivenName, Surname FROM Customers WHERE EXISTS ( SELECT * FROM SalesOrders WHERE ( OrderDate > '2001-07-13' ) AND ( Customers.ID = SalesOrders.CustomerID ) );
在本例中,对于 Customers 表中的每一行,该子查询检查该客户 ID 是否与在 2001 年 7 月 13 日之后下了订单的某位客户相对应。如果对应,则该查询将从主表提取该客户的名和姓。
EXISTS 测试不使用子查询的结果,它只检查子查询是否生成了任何行。因此,应用于以下两个子查询的存在测试返回相同的结果。它们是子查询,无法自行处理,因为它们引用的是属于主查询(但不属于子查询)的 Customers 表。
有关详细信息,请参见相关和不相关子查询。
SELECT * FROM Customers, SalesOrders WHERE ( OrderDate > '2001-07-13' ) AND ( Customers.ID = SalesOrders.CustomerID ) SELECT OrderDate FROM Customers, SalesOrders WHERE ( OrderDate > '2001-07-13' ) AND ( Customers.ID = SalesOrders.CustomerID );
SalesOrders 表中的哪些列出现在 SELECT 语句中并无多大关系,不过按照惯例,将使用 "SELECT *" 表示法。
您可以使用 NOT EXISTS 形式颠倒 EXISTS 测试的逻辑。在此情况下,如果子查询没有生成任何行,则该测试返回 TRUE,否则返回 FALSE。
您可能已经注意到,子查询中包含对 Customers 表中 ID 列的引用。对主表中的列或表达式的引用称作外部引用,并且这种子查询是相关的。从概念上说,SQL 处理上述查询的方式是遍历 Customers 表并为每个客户执行子查询。如果 SalesOrders 表中的订单日期晚于 2001 年 7 月 13 日,并且 Customers 表和 SalesOrders 表中的客户 ID 匹配,就会出现 Customers 表中的名和姓。因为子查询引用主查询,所以,本节中的子查询与前几节中的那些子查询不同,如果试图由子查询本身自行运行,将会返回错误。