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 的用法 » 查询和修改数据 » 使用子查询 » 优化程序自动将子查询转换为连接

 

跟在 IN 之后的子查询

仅当满足以下条件时,优化程序才会对跟在 IN 关键字之后的子查询进行转换:

  • 主查询不包含 GROUP BY 子句,并且不是集合查询,或子查询只返回一个值。

  • 子查询不包含 GROUP BY 子句。

  • 子查询不包含关键字 DISTINCT。

  • 子查询不是 UNION 查询。

  • 子查询不是集合查询。

  • 不得对合取式 'expression IN ( subquery-expression )' 取非。

示例

因此,由以下查询表示的请求 "查找还是部门领导的雇员的姓名",由于符合条件,将转化为连接查询。

SELECT GivenName, Surname
FROM Employees
WHERE EmployeeID IN (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName ='Finance' OR 
          DepartmentName = 'Shipping' ) );

不过,如果通过 UNION 查询表示请求 "查找自身是部门领导或客户的雇员的姓名",则不会将该查询转换为连接。

无法转换跟随在 IN 运算符之后的 UNION 查询
SELECT GivenName, Surname
FROM Employees
WHERE EmployeeID IN (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName='Finance' OR 
          DepartmentName = 'Shipping' )
   UNION
   SELECT CustomerID
   FROM SalesOrders);

类似地,如下所示,请求 "查找不是部门领导的雇员的姓名" 是以取非的子查询来表示,因此无法进行转换

SELECT GivenName, Surname
FROM Employees
  WHERE NOT EmployeeID IN (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName='Finance' OR 
          DepartmentName = 'Shipping' ) );

IN 或 ANY 子查询转化为连接所必需具备的条件是相同的。这是因为两个表达式逻辑上是等同的。

具有 IN 运算符的查询转换为具有 ANY 运算符的查询

在某些情况下,SQL Anywhere 将具有 IN 运算符的查询转换为具有 ANY 运算符的查询,并决定是否将子查询转换为连接。例如,以下两个表达式是等同的:

WHERE column-name IN( subquery-expression )
WHERE column-name = ANY( subquery-expression )

同样,以下两个查询是等同的:

SELECT GivenName, Surname
FROM Employees
WHERE EmployeeID IN (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName='Finance' OR 
          DepartmentName = 'Shipping' ) );
SELECT GivenName, Surname
FROM Employees
WHERE EmployeeID = ANY (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName='Finance' OR 
          DepartmentName = 'Shipping' ) );