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

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Daten abfragen und ändern » Unterabfragen verwenden » Optimierer: Automatische Konvertierung von Unterabfragen in Joins

 

Unterabfrage, die IN folgt

Der Optimierer konvertiert eine Unterabfrage, die einem Schlüsselwort IN folgt, nur, falls folgende Bedingungen erfüllt werden:

  • Die Hauptabfrage enthält keine GROUP BY-Klausel und ist keine Aggregatabfrage, oder die Unterabfrage gibt genau einen Wert zurück.

  • Die Unterabfrage enthält keine GROUP BY-Klausel.

  • Die Unterabfrage enthält kein DISTINCT-Schlüsselwort.

  • Die Unterabfrage ist keine UNION-Abfrage.

  • Die Unterabfrage ist keine Aggregatabfrage.

  • Die Verbindung 'Ausdruck IN ( Unterabfragen_Ausdruck )' darf nicht negiert werden.

Beispiel

Die Anforderung "Finde die Namen der Mitarbeiter, die auch Abteilungsleiter sind" wird mit der folgenden Abfrage ausgedrückt und in eine Join-Abfrage konvertiert, da sie die Bedingungen erfüllt.

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

Anders die Anforderung "Finde die Namen der Mitarbeiter, die Abteilungsleiter oder Kunden sind". Sie wird nicht in einen Join umgewandelt, wenn sie durch die UNION-Abfrage ausgedrückt wird.

Eine UNION-Abfrage nach dem Operator IN kann nicht umgewandelt werden
SELECT GivenName, Surname
FROM Employees
WHERE EmployeeID IN (
   SELECT DepartmentHeadID
   FROM Departments
   WHERE ( DepartmentName='Finance' OR 
          DepartmentName = 'Shipping' )
   UNION
   SELECT CustomerID
   FROM SalesOrders);

Die Anforderung "Finde die Namen der Mitarbeiter, die keine Abteilungsleiter sind" wird als negativ interpretierte Unterabfrage (siehe unten) formuliert und nicht konvertiert.

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

Die Bedingungen, die zur Konvertierung einer IN- oder ANY-Unterabfrage in einen Join erforderlich sind, sind identisch. Der Grund hierfür ist, dass beide Ausdrücke logisch gleichwertig sind.

Konvertierung einer Abfrage mit dem Operator IN in eine Abfrage mit dem Operator ANY

In einigen Fällen konvertiert SQL Anywhere eine Abfrage mit dem Operator IN in eine Abfrage mit dem Operator ANY und entscheidet dann, ob die Unterabfrage in einen Join konvertiert wird. Die folgenden beiden Ausdrücke sind beispielsweise gleichwertig:

WHERE Spaltenname IN( Unterabfragen_Ausdruck )
WHERE Spaltenname = ANY( Unterabfragen_Ausdruck) 

Die folgenden beiden Abfragen sind ebenfalls gleichwertig:

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