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 ANY, ALL oder SOME folgt

Eine Unterabfrage, die einem der Schlüsselwörter ANY, ALL oder SOME folgt, wird ein quantifizierter Vergleich genannt. Der Optimierer konvertiert diese Unterabfragen in Joins, sofern 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 'AusdruckVergleichsoperator { ANY | SOME } ( Unterabfragen_Ausdruck )' darf nicht negiert werden.

  • Die Verbindung 'AusdruckVergleichsoperator ( ALL ( Unterabfragen_Ausdruck )' muss negiert werden.

Die ersten vier Bedingungen sind relativ klar.

Beispiel

Die Anforderung, "Wann haben Frau Clarke und Suresh ihre Bestellungen aufgegeben, und welcher Verkäufer hat sie bedient?", kann als Unterabfrage behandelt werden:

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

Sie kann alternativ auch in einem Join-Format verarbeitet werden:

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

Anders bei der Anforderung "Wann haben Frau Clarke, Suresh und ein Mitarbeiter, der auch Kunde ist, ihre Bestellungen aufgegeben?". Sie muss als Union-Abfrage formuliert werden, und eine Umwandlung in einen Join ist daher nicht möglich:

SELECT OrderDate, SalesRepresentative
FROM SalesOrders
WHERE CustomerID = ANY (
   SELECT ID
   FROM Customers
   WHERE Surname = 'Clarke' OR GivenName = 'Suresh'
   UNION
   SELECT EmployeeID
   FROM Employees );

Ähnlich würde die Anforderung "Finde die Bestellungs-IDs und die Kunden-IDs derjenigen Bestellungen, die nicht nach den ersten Versanddaten aller Produkte versandt wurden" als Aggregatabfrage ausgedrückt werden. Sie kann daher nicht in einen Join umgewandelt werden:

SELECT ID, CustomerID
FROM SalesOrders
WHERE NOT OrderDate > ALL (
   SELECT FIRST ( ShipDate )
   FROM SalesOrderItems 
   ORDER BY ShipDate );
Negativ-Interpretation von Unterabfragen mit den Operatoren ANY und ALL

Das fünfte Kriterium ist etwas schwerer zu verstehen. Abfragen der folgenden Formate werden in Joins umgewandelt:

SELECT Auswahlliste 
FROM Tabelle 
WHERE NOT Ausdruck Vergleichsoperator ALL ( Unterabfragen_Ausdruck ) 
SELECT Auswahlliste 
FROM Tabelle 
WHERE Ausdruck Vergleichsoperator ANY ( Unterabfragen_Ausdruck)

Die folgenden Abfragen werden jedoch nicht in Joins umgewandelt:

SELECT Auswahlliste 
FROM Tabelle 
WHERE Ausdruck Vergleichsoperator ALL ( Unterabfragen_Ausdruck)
SELECT Auswahlliste 
FROM Tabelle 
WHERE NOT Ausdruck Vergleichsoperator ANY ( Unterabfragen_Ausdruck)

Die ersten beiden Abfragen sind gleichwertig, ebenso wie die letzten beiden. Es wurde schon erwähnt, dass der Operator ANY dem Operator OR gleichwertig ist, aber eine variable Anzahl von Argumenten hat. Der Operator ALL ist in diesem Sinne dem Operator AND gleichwertig. Die folgenden beiden Ausdrücke sind beispielsweise gleichwertig:

NOT ( ( X > A ) AND ( X > B ) )
( X <= A ) OR ( X <= B )

Ebenfalls sind die folgenden beiden Ausdrücke gleichwertig:

WHERE NOT OrderDate > ALL (
   SELECT FIRST ( ShipDate )
   FROM SalesOrderItems
   ORDER BY ShipDate )
WHERE OrderDate <= ANY (
   SELECT FIRST ( ShipDate )
   FROM SalesOrderItems
   ORDER BY ShipDate )
Negativinterpretationen der Ausdrücke ANY und ALL

Allgemein sind die folgenden Ausdrücke gleichwertig:

 NOT SpaltennameOperator ANY (Unterabfragen_Ausdruck) 
SpaltennameInverser_Operator ALL (Unterabfragen_Ausdruck) 

Diese Ausdrücke sind allgemein ebenfalls gleichwertig:

NOT SpaltennameOperator ALL (Unterabfragen_Ausdruck)
SpaltennameInverser_Operator ANY (Unterabfragen_Ausdruck)

Dabei gilt: Inverser_Operator wird erlangt, indem Operator negiert wird, wie die folgende Tabelle zeigt:

Operator Inverser_Operator
= <>
< =>
> =<
=< >
=> <
<> =