Aus der Dokumentation zu CONNECT_BY_ISCYCLE
:
Der CONNECT_BY_ISCYCLE
Pseudospalte gibt 1
zurück wenn die aktuelle Zeile ein Kind hat, das auch ihr Vorfahre ist
und das auf CYCLE
:
Eine Zeile wird als Zyklus angesehen, wenn eine ihrer Vorgängerzeilen die gleichen Werte für die Zyklusspalten hat.
In Ihrem Beispiel Zeile 2
hat ein Kind, das auch sein Vorfahre ist, aber seine id
wurde noch nicht zurückgegeben.
Mit anderen Worten, CONNECT_BY_ISCYCLE
überprüft die Kinder (die noch zurückgegeben werden müssen), während CYCLE
überprüft die aktuelle Zeile (die bereits zurückgegeben wird).
CONNECT BY
ist zeilenbasiert, während rekursiv CTE
sind satzbasiert.
Beachten Sie, dass die Dokumentation von Oracle auf CYCLE
erwähnt eine "Ahnenreihe". Im Allgemeinen gibt es jedoch kein Konzept einer "Vorfahrenzeile" in einem rekursiven CTE
. Es handelt sich um eine mengenbasierte Operation, die Ergebnisse vollständig aus dem Baum heraus liefern kann. Im Allgemeinen können der Ankerteil und der rekursive Teil sogar die unterschiedlichen Tabellen verwenden.
Seit rekursivem CTE
sind normalerweise Wird verwendet, um Hierarchiebäume zu erstellen, Oracle
beschlossen, eine Zyklusprüfung hinzuzufügen. Aber aufgrund des mengenbasierten Weges der rekursive CTE
's funktionieren, ist es im Allgemeinen unmöglich zu sagen, ob der nächste Schritt einen Zyklus erzeugt oder nicht, da ohne eine klare Definition der "Ahnenreihe" auch keine Zyklusbedingung definiert werden kann.
Um den "nächsten" Schritt auszuführen, muss der gesamte "aktuelle" Satz verfügbar sein, aber um jede Zeile des aktuellen Satzes (einschließlich der Zyklusspalte) zu generieren, brauchen wir nur die Ergebnisse der "nächsten" Operation.
Es ist kein Problem, wenn der aktuelle Satz immer aus einer einzigen Zeile besteht (wie in CONNECT BY
), aber es ist ein Problem, wenn die rekursive Operation auf einer Menge als Ganzes definiert ist.
Ich habe mir Oracle 11
nicht angeschaut noch, aber SQL Server
implementiert rekursiven CTE
durch einfaches Ausblenden eines CONNECT BY
hinter ihnen, was das Platzieren zahlreicher Einschränkungen erfordert (die alle effektiv alle satzbasierten Operationen verbieten).
PostgreSQL
Die Implementierung von hingegen ist wirklich mengenbasiert:Sie können jede Operation mit dem Ankerteil im rekursiven Teil ausführen. Es hat jedoch keine Möglichkeit, Zyklen zu erkennen, da Zyklen von vornherein nicht definiert sind.
Wie bereits erwähnt, MySQL
implementiert CTE
nicht überhaupt (es implementiert HASH JOIN
nicht 's oder MERGE JOIN
s auch, nur die verschachtelten Schleifen, also wundern Sie sich nicht allzu sehr).
Ironischerweise habe ich heute einen Brief zu genau diesem Thema erhalten, das ich in meinem Blog behandeln werde.
Aktualisierung:
Rekursiver CTE
's in SQL Server
sind nicht mehr als CONNECT BY
verkleidet. Siehe diesen Artikel in meinem Blog für schockierende Details:
- SQL Server:Sind die rekursiven CTEs wirklich satzbasiert?