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 句を含んでおらず、集計クエリでない。または、サブクエリが 1 つの値を返す。

  • サブクエリが 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 サブクエリがジョインに変換されるために必要な条件は、同じです。これは、2 つの式が論理的には同等であるためです。

ANY 演算子を使用するクエリに変換される、IN 演算子を使用するクエリ

場合によっては、SQL Anywhere は IN 演算子を使用するクエリを、ANY 演算子を使用するクエリに変換し、サブクエリをジョインに変換するかどうかを決定します。たとえば、次の 2 つの式は同等です。

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

同様に、次の 2 つのクエリは同等です。

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' ) );