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

 

Einzeilige und mehrzeilige Unterabfragen

Unterabfragen, die nur eine oder null Zeilen an die äußere Anweisung zurückgeben können, werden Einzeilen-Unterabfragen genannt. Einzeilen-Unterabfragen sind Unterabfragen, die mit einem Vergleichsoperator in einer WHERE- oder HAVING-Klausel verwendet werden.

Unterabfragen, die mehr als eine Zeile (aber nur eine Spalte) an die äußere Anweisung zurückgeben können, werden Mehrzeilen-Unterabfragen genannt. Mehrzeilen-Unterabfragen sind Unterabfragen, die in einer IN-, ANY- oder ALL-Klausel verwendet werden.

Beispiel 1: Einzeilen-Unterabfrage

Sie speichern Produktinformationen in einer Tabelle namens "Products", und Informationen zu Bestellungen in der Tabelle "SalesOrdersItems". Die Tabelle "Products" enthält die Daten zu den einzelnen Produkten. Die Tabelle "SalesOrdersItems" enthält Daten zu den Bestellungen der Kunden. Wenn das Unternehmen Produkte nachbestellt, sobald der Lagerstand auf unter 50 Stück sinkt, kann die Frage "Welche Produkte sind unter dem Mindest-Lagerbestand?" mit folgender Abfrage beantwortet werden.

SELECT ID, Name, Description, Quantity
FROM Products
WHERE Quantity < 50;

Ein zielführenderes Ergebnis allerdings würde berücksichtigen, wie häufig ein Produkt bestellt wird, weil ein geringer Lagerbestand bei häufig nachgefragten Produkten bedenklicher ist als bei solchen, die kaum bestellt werden.

Sie können eine Unterabfrage verwenden, um die durchschnittliche Anzahl von Artikeln zu ermitteln, die ein Kunde bestellt, und dann diesen Mittelwert in der Hauptabfrage verwenden, um Produkte zu finden, für die fast nur der Mindest-Lagerbestand vorhanden ist. Folgende Abfrage sucht die Namen und Beschreibungen der Produkte, deren Anzahl weniger als doppelt so hoch ist wie die durchschnittliche Anzahl der Artikel, die von einem Kunden bestellt werden.

SELECT Name, Description
FROM Products WHERE Quantity <  2 * (
   SELECT AVG( Quantity )
   FROM SalesOrderItems
   );

In der WHERE-Klausel helfen Unterabfragen bei der Auswahl der im Abfrageergebnis anzuzeigenden Zeilen aus den Tabellen, die in der FROM-Klausel angegeben werden. In der HAVING-Klausel helfen Sie bei der Auswahl von Zeilengruppen, die von der GROUP BY-Klausel der Hauptabfrage angegeben wurden und in den Ergebnissen der Abfrage erscheinen sollen.

Beispiel 2: Einzeilen-Unterabfrage

Das folgende Beispiel einer Einzeilen-Unterabfrage berechnet den durchschnittlichen Preis der Produkte in der Products-Tabelle. Der Mittelwert wird anschließend an die WHERE-Klausel der äußeren Abfrage übergeben. Die äußere Abfrage gibt ID, Name und UnitPrice aller Produkte zurück, die weniger teuer als der Mittelwert sind:

SELECT ID, Name, UnitPrice
FROM Products
WHERE UnitPrice <
  ( SELECT AVG( UnitPrice ) FROM Products )
ORDER BY UnitPrice DESC;
ID Name UnitPrice
401 Baseball Cap 10.00
300 Tee Shirt 9.00
400 Baseball Cap 9.00
500 Visor 7.00
501 Visor 7.00
Beispiel 3: Einfache Mehrzeilen-Unterabfrage mit IN

Angenommen, Sie wollen Artikel mit niedrigem Lagerbestand ermitteln und auch Bestellungen für diese Artikel erfassen. Sie könnten eine SELECT-Anweisung ausführen, die eine Unterabfrage in der WHERE-Klausel enthält, und zwar folgendermaßen:

SELECT *
FROM SalesOrderItems
WHERE ProductID IN
   (  SELECT ID
       FROM Products
       WHERE Quantity < 20 )
ORDER BY ShipDate DESC;

In diesem Beispiel erstellt die Unterabfrage eine Liste aller Werte in der Spalte ID der Tabelle "Products", welche die Suchbedingung der WHERE-Klausel erfüllen. Die Unterabfrage gibt anschließend eine Reihe von Zeilen, aber nur eine einzige Spalte zurück. Das Schlüsselwort IN behandelt jeden Wert als Teil einer Menge und testet, ob jede Zeile in der Hauptabfrage Teil der Menge ist.

Beispiel 4: Mehrzeilen-Unterabfragen, die die Verwendung von IN, ANY und ALL vergleichen

Zwei Tabellen in der SQL Anywhere-Beispieldatenbank enthalten Ergebnisse mit Finanzdaten. Bei der Tabelle "FinancialCodes" handelt es sich um eine Tabelle mit den verschiedenen Codes für Finanzdaten und deren Bedeutung. Um die Umsätze ("revenue") aus der Tabelle "FinancialData" aufzulisten, geben Sie Folgendes ein:

SELECT *
FROM FinancialData
WHERE Code IN
    ( SELECT Code
        FROM FinancialCodes
        WHERE type = 'revenue' );
Year Quarter Code Amount
1999 Q1 r1 1023
1999 Q2 r1 2033
1999 Q3 r1 2998
1999 Q4 r1 3014
2000 Q1 r1 3114
... ... ... ...

Die Schlüsselwörter ANY und ALL können auf ähnliche Weise verwendet werden. Beispiel: Die folgende Abfrage liefert dieselben Ergebnisse wie die vorherige Abfrage, verwendet jedoch das Schlüsselwort ANY:

SELECT *
FROM FinancialData
WHERE FinancialData.Code = ANY
   (  SELECT FinancialCodes.Code
       FROM FinancialCodes
       WHERE type = 'revenue' );

Die Bedingung =ANY ist identisch mit der IN-Bedingung. Darüber hinaus kann ANY aber auch mit Ungleichheits-Operatoren, wie z.B. < oder > verwendet werden, um Unterabfragen flexibler zu gestalten.

Das Schlüsselwort ALL ist ähnlich dem Wort ANY. Folgende Abfrage listet zum Beispiel Finanzdaten auf, bei denen es sich nicht um Umsätze handelt:

SELECT *
FROM FinancialData
WHERE FinancialData.Code <> ALL
   (  SELECT FinancialCodes.Code
       FROM FinancialCodes
      WHERE type = 'revenue' );

Diese Anweisung entspricht dem Befehl mit NOT IN:

SELECT *
FROM FinancialData
WHERE FinancialData.Code NOT IN
   (  SELECT FinancialCodes.Code
      FROM FinancialCodes
      WHERE type = 'revenue' );