Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询和修改数据 » 使用子查询

 

单行和多行子查询

只能向外部语句返回一行或零行的子查询称为单行子查询。单行子查询是在 WHERE 或 HAVING 子句中与比较运算符一起使用的子查询。

可向外部语句返回多行(但只有一列)的子查询称为多行子查询。多行子查询与 IN、ANY 或 ALL 子句一起使用。

示例 1:单行子查询

您将产品特有的信息存储在一个名为 Products 的表中,将与销售订单有关的信息存储在另一个名为 SalesOrdersItems 的表中。Products 表包含与各种产品有关的信息。SalesOrdersItems 表包含与客户订单有关的信息。如果公司在产品库存量不足 50 的情况下再次订购产品,就可以通过以下查询回答“哪些产品将要缺货?”这一问题:

SELECT ID, Name, Description, Quantity
FROM Products
WHERE Quantity < 50;

然而,我们应考虑某产品的订购频率,其结果会对我们更有帮助,因为与很少订购的产品相比,我们更关心频繁订购的产品的库存量是否不足。

您可以使用子查询来确定客户订购的产品的平均数,然后在主查询中使用该平均数查找将要缺货的产品。对于数目小于客户订购的每一类产品的平均数两倍的产品,以下查询将查找这些产品的名称和说明。

SELECT Name, Description
FROM Products WHERE Quantity <  2 * (
   SELECT AVG( Quantity )
   FROM SalesOrderItems
   );

在 WHERE 子句中,子查询帮助从 FROM 子句中列出的表中选择出现在查询结果中的行。在 HAVING 子句中,子查询帮助选择在查询结果中出现的行组,这些行组是由主查询的 GROUP BY 子句指定的。

示例 2:单行子查询

以下是一个单行子查询的示例,用于计算 Products 表中产品的平均价格。该平均价格随后被传递给外部查询的 WHERE 子句。外部查询会返回低于平均价格的所有产品的 ID、Name 和 UnitPrice。

SELECT ID, Name, UnitPrice
FROM Products
WHERE UnitPrice <
  ( SELECT AVG( UnitPrice ) FROM Products )
ORDER BY UnitPrice DESC;
ID Name UnitPrice
401 Baseball Cap 10.00
300 Tee Shirt 9.00
400 Baseball Cap 9.00
500 Visor 7.00
501 Visor 7.00
示例 3:使用 IN 的简单多行子查询

假设您想要找出库存不足的产品,还要同时找出这些产品的订单。您可以执行一个 SELECT 语句,其 WHERE 子句中包含一个子查询,如下所示:

SELECT *
FROM SalesOrderItems
WHERE ProductID IN
   (  SELECT ID
       FROM Products
       WHERE Quantity < 20 )
ORDER BY ShipDate DESC;

在此示例中,该子查询会生成一个列表,其中包含 Products 表内 ID 列中的所有值,这些值符合 WHERE 子句搜索条件。该子查询随后会返回一组行,但只返回一个列。IN 关键字将每个值都视为集合的一个成员,并测试主查询的每个行是否都是该集合的成员。

示例 4:多行子查询与使用 IN、ANY 和 ALL 的对比

SQL Anywhere 示例数据库中有两个表包含财务结果数据。FinancialCodes 表是一个保存财务数据的不同代码及其含义的表。要列出 FinancialData 表中的收入项,请执行以下查询:

SELECT *
FROM FinancialData
WHERE Code IN
    ( SELECT Code
        FROM FinancialCodes
        WHERE type = 'revenue' );
Year Quarter Code Amount
1999 Q1 r1 1023
1999 Q2 r1 2033
1999 Q3 r1 2998
1999 Q4 r1 3014
2000 Q1 r1 3114
... ... ... ...

可采用类似方式使用 ANY 和 ALL 关键字。例如,以下查询和上一个查询返回同样的结果,但是使用了 ANY 关键字:

SELECT *
FROM FinancialData
WHERE FinancialData.Code = ANY
   (  SELECT FinancialCodes.Code
       FROM FinancialCodes
       WHERE type = 'revenue' );

虽然 =ANY 条件与 IN 条件完全相同,但 ANY 还可以与不等式(如 <>)一起使用,从而能够更灵活地使用子查询。

ALL 关键字与 ANY 类似。例如,以下查询列出非收入财务数据:

SELECT *
FROM FinancialData
WHERE FinancialData.Code <> ALL
   (  SELECT FinancialCodes.Code
       FROM FinancialCodes
      WHERE type = 'revenue' );

这等同于下面使用 NOT IN 的命令:

SELECT *
FROM FinancialData
WHERE FinancialData.Code NOT IN
   (  SELECT FinancialCodes.Code
      FROM FinancialCodes
      WHERE type = 'revenue' );