Collection Contents 上一页 下一页 PDF

ASA SQL 用户指南

使用子查询

存在测试


在子查询比较测试中使用的子查询和在集合成员资格测试中使用的子查询都从子查询表返回数据值。不过,有时候您可能更关心子查询是否返回一些结果,而不是返回哪些结果。存在测试 (EXISTS) 就是用来检查子查询是否生成一些查询结果行的。如果子查询生成一行或多行结果,则 EXISTS 测试就返回 TRUE。否则,它就返回 FALSE。

示例 

下面是一个使用子查询表示的请求:[哪些客户在 2001 年 7 月 13 日以后下了订单?]

SELECT fname, lname
FROM customer
WHERE EXISTS (
   SELECT *
   FROM sales_order
   WHERE (order_date > '2001-07-13') AND
    (customer.id = sales_order.cust_id))
fname lname
Almen de Joie
Grover Pendelton
Ling Ling Andrews
Bubba Murphy
有关存在测试的说明 

在这里,对于 customer 表中的每一行,该子查询检查客户 ID 是否与在 2001 年 7 月 13 日之后下了订单的某位客户的 ID 相对应。如果相对应,则该查询将从主表提取该客户的名和姓。

EXISTS 测试不使用子查询的结果,它只检查该子查询是否生成一些行。因此,应用于以下两个子查询的存在测试返回相同的结果。它们是子查询并且无法自行处理,因为这两个子查询引用属于主查询(但不属于子查询)的客户表。

有关详细信息,请参见相关子查询

SELECT *
FROM sales_order
WHERE (order_date > '2001-07-13') AND (customer.id = sales_order.cust_id)
SELECT ship_date
FROM sales_order
WHERE (order_date > '2001-07-13') AND (customer.id = sales_order.cust_id)

sales_order 表中的哪些列出现在 SELECT 语句中并无多大关系,不过,按照惯例,使用"SELECT *"表示法。

对存在测试取非 

您可以采用 NOT EXISTS 的形式颠倒 EXISTS 测试的逻辑。在此情况下,如果子查询没有生成任何行,则该测试返回 TRUE,否则返回 FALSE。

相关子查询 

您可能已经注意到,子查询中包含对 customer 表上的 id 列的引用。对主表中的列或表达式的引用被称作外部引用,并且这种子查询是相关的。在概念上,SQL 处理上述查询的方式是遍历 customer 表并为每一客户执行子查询。如果 sales_order 表中的订单日期晚于 2001 年 7 月 13 日,并且 customer 表和 sales_order 表中的客户 ID 相匹配,则 customer 表中的名和姓就会显示出来。因为子查询引用主查询,所以,本节中的子查询与前几节中的那些子查询不同,如果您尝试由它本身来运行,将会返回错误。


Collection Contents 上一页 下一页 PDF