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 » Allgemeine Tabellenausdrücke

 

Rekursive allgemeine Tabellenausdrücke

Allgemeine Tabellenausdrücke können rekursiv sein. Sie sind dann rekursiv, wenn das RECURSIVE-Schlüsselwort unmittelbar nach WITH verwendet wird. Eine einzelne WITH-Klausel kann mehrere rekursive Ausdrücke enthalten und sie kann sowohl rekursive als auch nicht-rekursive allgemeine Tabellenausdrücke enthalten.

Mit einer Rekursion ist es viel einfacher, Tabellen zu durchsuchen, die Baum- oder baumartige Datenstrukturen haben. Die einzige Möglichkeit, so eine Struktur mit einer einzigen Anweisung zu durchsuchen, ohne rekursive Ausdrücke zu verwenden, besteht darin, die Tabelle einmal pro möglicher Ebene mit sich selbst zu verknüpfen. Wenn zum Beispiel die Hierarchie maximal sieben Ebenen hat, müssen Sie die Tabelle "Employees" sieben Mal mit sich selbst verknüpfen. Wenn die Firma umorganisiert wird und eine neue Managementebene eingeführt wird, müssen Sie die Abfrage neu schreiben.

Rekursive allgemeine Tabellenausdrücke sind eine praktische Methode, Abfragen zu schreiben, die Beziehungen mit beliebiger Tiefe zurückgeben. Bei einer Tabelle zum Beispiel, die Unterstellungsbeziehungen in einer Firma darstellt, können Sie einfach eine Abfrage schreiben, die alle Mitarbeiter zurückgibt, die einer bestimmten Person unterstellt sind.

Betrachten Sie zum Beispiel den Fall, dass die Abteilung mit den meisten Mitarbeitern ermittelt werden soll. Die Tabelle "Employess" in der SQL-Anywhere-Beispieldatenbank listet alle Mitarbeiter in einer fiktiven Firma auf und gibt an, in welcher Abteilung jeder arbeitet. Die folgende Abfrage listet die ID-Codes der Abteilungen und die Gesamtzahl der Mitarbeiter in ihnen auf.

SELECT DepartmentID, COUNT( * ) AS n
FROM Employees
GROUP BY DepartmentID;

Mit der folgenden Abfrage können Sie die Abteilung extrahieren, die die meisten Mitarbeiter hat:

SELECT DepartmentID, n
FROM ( SELECT DepartmentID, COUNT( * ) AS n
       FROM Employees GROUP BY DepartmentID ) AS a
WHERE a.n =
  ( SELECT MAX( n )
    FROM ( SELECT DepartmentID, COUNT( * ) AS n
           FROM Employees GROUP BY DepartmentID ) AS b );

Zwar liefert diese Anweisung das korrekte Ergebnis, doch hat sie auch Nachteile. Der erste Nachteil ist, dass durch die wiederholte Unterabfrage die Anweisung weniger effizient ist. Der zweite Nachteil ist, dass diese Anweisung keine klare Verbindung zwischen den Unterabfragen herstellt.

Dies umgehen Sie, indem Sie eine Ansicht erstellen und sie dazu verwenden, die Abfrage neu zu formulieren. Dieses Vorgehen vermeidet die oben erwähnten Probleme.

CREATE VIEW CountEmployees( DepartmentID, n ) AS
   SELECT DepartmentID, COUNT( * ) AS n
   FROM Employees GROUP BY DepartmentID; 

SELECT DepartmentID, n
   FROM CountEmployees
   WHERE n = ( SELECT MAX( n )
               FROM CountEmployees );

Der Nachteil dieser Vorgehensweise besteht darin, dass eine bestimmte Menge an Overhead erforderlich ist, weil der Datenbankserver die Systemtabellen aktualisieren muss, wenn die Ansicht erstellt wird. Wenn die Ansicht häufig verwendet wird, ist dieses Vorgehen vernünftig. Wenn allerdings die Ansicht nur einmal innerhalb einer bestimmten SELECT-Anweisung verwendet wird, ist die bevorzugte Methode, stattdessen einen allgemeinen Tabellenausdruck zu verwenden. Weitere Hinweise zu allgemeinen Tabellenausdrücken finden Sie unter Allgemeine Tabellenausdrücke verwenden.

Rekursive allgemeine Tabellenausdrücke enthalten eine Anfangs-Unterabfrage, oder einen Initialwert (Seed-Wert), und eine rekursive Unterabfrage, die bei jeder Wiederholung zusätzliche Zeilen der Ergebnismenge hinzufügt. Die zwei Teile können nur mit dem UNION ALL-Operator verbunden werden. Die Anfangs-Unterabfrage ist eine gewöhnliche nicht-rekursive Abfrage und wird zuerst abgearbeitet. Der rekursive Abschnitt enthält eine Referenz zu den Zeilen, die während der vorherigen Wiederholung hinzugefügt wurden. Die Rekursion stoppt automatisch, sobald eine Wiederholung keine neuen Zeilen mehr generiert. Es gibt keine Möglichkeit, Zeilen zu referenzieren, die vor der vorherigen Wiederholung ausgewählt wurden.

Die Auswahlliste der rekursiven Unterabfrage muss der der Anfangs-Unterabfrage in Anzahl und Datentyp entsprechen. Wenn eine automatische Konvertierung der Datentypen nicht durchgeführt werden kann, passen Sie explizit die Ergebnisse der einen Unterabfrage an, damit sie jenen in der anderen Unterabfrage entsprechen.


Hierarchische Daten auswählen
Einschränkungen für rekursive allgemeine Tabellenausdrücke