Dalla documentazione su CONNECT_BY_ISCYCLE
:
Il CONNECT_BY_ISCYCLE
pseudocolonna restituisce 1
se la riga corrente ha un figlio che è anche il suo antenato
e quello su CYCLE
:
Una riga è considerata un ciclo se una delle righe precedenti ha gli stessi valori per le colonne del ciclo.
Nel tuo esempio, riga 2
ha un figlio che è anche il suo antenato, ma il suo id
non è stato ancora restituito.
In altre parole, CONNECT_BY_ISCYCLE
controlla i figli (che devono ancora essere restituiti), mentre CYCLE
controlla la riga corrente (che è già stato restituito).
CONNECT BY
è basato su righe, mentre ricorsivo CTE
sono basati su insiemi.
Nota che la documentazione di Oracle su CYCLE
menziona una "fila di antenati". Tuttavia, in generale, non esiste il concetto di "riga di antenati" in un CTE
ricorsivo . È un'operazione basata su set che può produrre risultati completamente fuori dall'albero. In generale, la parte di ancoraggio e la parte ricorsiva possono utilizzare anche le diverse tabelle.
Dal ricorsivo CTE
sono solitamente usato per costruire alberi gerarchici, Oracle
deciso di aggiungere un controllo del ciclo. Ma a causa del modo basato sul set, il ricorsivo CTE
's opera, è generalmente impossibile dire se il passaggio successivo genererà un ciclo o meno, perché senza una chiara definizione della "riga predecessore" non è nemmeno possibile definire la condizione del ciclo.
Per eseguire il passaggio "successivo", l'intero set "corrente" deve essere disponibile, ma per generare ogni riga del set corrente (che include la colonna del ciclo) dobbiamo solo avere i risultati dell'operazione "successivo".
Non è un problema se il set corrente è sempre composto da una singola riga (come in CONNECT BY
), ma è un problema se l'operazione ricorsiva è definita su un insieme nel suo insieme.
Non ho esaminato Oracle 11
ancora, ma SQL Server
implementa CTE
ricorsivo 's semplicemente nascondendo un CONNECT BY
dietro di loro, il che richiede l'introduzione di numerose restrizioni (tutte le quali vietano effettivamente tutte le operazioni basate su insiemi).
PostgreSQL
L'implementazione, invece, è veramente set-based:puoi fare qualsiasi operazione con la parte di ancoraggio nella parte ricorsiva. Tuttavia, non ha alcun mezzo per rilevare i cicli, perché i cicli non sono definiti in primo luogo.
Come accennato in precedenza, MySQL
non implementa CTE
's affatto (non implementa HASH JOIN
's o MERGE JOIN
Inoltre, solo i loop nidificati, quindi non sorprenderti molto).
Ironia della sorte, oggi ho ricevuto una lettera proprio su questo argomento, che tratterò nel mio blog.
Aggiornamento:
CTE
ricorsivo è in SQL Server
non sono più di CONNECT BY
sotto mentite spoglie. Vedi questo articolo nel mio blog per dettagli scioccanti:
- SQL Server:i CTE ricorsivi sono davvero basati su set?