仅当满足以下条件时,优化程序才会对跟在 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 查询表示请求 "查找自身是部门领导或客户的雇员的姓名",则不会将该查询转换为连接。
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 子查询转化为连接所必需具备的条件是相同的。这是因为两个表达式逻辑上是等同的。
在某些情况下,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' ) ); |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |