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 子句中出现子查询时的情况,其形式如下

SELECT select-list 
FROM table 
WHERE
[NOT] expression comparison-operator ( subquery-expression ) 
| [NOT] expression comparison-operator { ANY | SOME } ( subquery-expression ) 
| [NOT] expression comparison-operator ALL ( subquery-expression ) 
| [NOT] expression IN ( subquery-expression )
| [NOT] EXISTS ( subquery-expression ) 
GROUP BY group-by-expression 
HAVING search-condition

例如,考虑以下请求:"Clarke 女士和 Suresh 女士何时下的订单,是通过哪些销售代表下的订单?"可以通过以下查询回答上述请求:

SELECT OrderDate, SalesRepresentative
FROM SalesOrders
WHERE CustomerID IN (
   SELECT ID
   FROM Customers
   WHERE Surname = 'Clarke' OR GivenName = 'Suresh' );
OrderDate SalesRepresentative
2001-01-05 1596
2000-01-27 667
2000-11-11 467
2001-02-04 195
... ...

该子查询生成与其姓名在 WHERE 子句中列出的两个客户相对应的客户 ID 的列表,并且主查询查找与这两位女士的订单相对应的订单日期和销售代表。

可以使用连接来回答同样的问题。下面是该查询的替代形式,使用了两表连接:

SELECT OrderDate, SalesRepresentative
FROM SalesOrders, Customers
WHERE CustomerID=Customers.ID AND
  ( Surname = 'Clarke' OR GivenName = 'Suresh' );

此查询形式将 SalesOrders 表连接到 Customers 表,以查找每个客户的订单,然后只返回 Suresh 和 Clarke 的记录。

子查询有效但连接无效的情形

在某些情况下,子查询有效,但连接无效。例如:

SELECT Name, Description, Quantity
FROM Products
WHERE Quantity <  2 * (
   SELECT AVG( Quantity )
   FROM SalesOrderItems );
name Description Quantity
Tee Shirt Tank Top 28
Baseball Cap Wool cap 12
Visor Cloth Visor 36
... ... ...

在此例中,内部查询是汇总查询,而外部查询不是汇总查询,因此,无法通过一个简单连接来合并这两个查询。

另请参见

跟在比较运算符之后的子查询
跟在 ANY、ALL 或 SOME 之后的子查询
跟在 IN 之后的子查询
跟在 EXISTS 之后的子查询