sql >> Database >  >> RDS >> Oracle

Cyclusdetectie met recursieve subqueryfactoring

Uit documentatie op CONNECT_BY_ISCYCLE :

De CONNECT_BY_ISCYCLE pseudokolom retourneert 1 als de huidige rij een kind heeft dat ook zijn voorouder is

en dat op CYCLE :

Een rij wordt beschouwd als een cyclus als een van zijn voorouderrijen dezelfde waarden heeft voor de cycluskolommen.

In uw voorbeeld rij 2 heeft wel een kind dat ook zijn voorouder is, maar zijn id is nog niet teruggestuurd.

Met andere woorden, CONNECT_BY_ISCYCLE controleert de kinderen (die nog moeten worden geretourneerd), terwijl CYCLE controleert de huidige rij (die al is geretourneerd).

CONNECT BY is rijgebaseerd, terwijl recursief CTE 's zijn set-gebaseerd.

Merk op dat de documentatie van Oracle over CYCLE noemt een "voorouderrij". Over het algemeen is er echter geen concept van een "voorouderrij" in een recursieve CTE . Het is een op een set gebaseerde bewerking die resultaten kan opleveren die volledig uit de boom zijn. Over het algemeen kunnen het ankergedeelte en het recursieve gedeelte zelfs de verschillende tabellen gebruiken.

Sinds recursieve CTE 's zijn meestal gebruikt om hiërarchiebomen te bouwen, Oracle besloten om een ​​cycluscontrole toe te voegen. Maar vanwege de set-gebaseerde manier is de recursieve CTE 's werken, is het over het algemeen onmogelijk om te zeggen of de volgende stap een cyclus genereert of niet, omdat zonder een duidelijke definitie van de "voorouderlijke rij" cyclusconditie ook niet kan worden gedefinieerd.

Om de "volgende" stap uit te voeren, moet de hele "huidige" set beschikbaar zijn, maar om elke rij van de huidige set (inclusief de cycluskolom) te genereren, hebben we alleen de resultaten van de "volgende" bewerking nodig.

Het is geen probleem als de huidige set altijd uit één rij bestaat (zoals in CONNECT BY ), maar het is een probleem als de recursieve bewerking op een verzameling als geheel wordt gedefinieerd.

Niet gekeken naar Oracle 11 nog, maar SQL Server implementeert recursieve CTE door gewoon een CONNECT BY . te verbergen achter hen, wat het plaatsen van talrijke beperkingen vereist (die alle in feite alle op sets gebaseerde bewerkingen verbieden).

PostgreSQL 's implementatie daarentegen is echt set-gebaseerd:u kunt elke bewerking uitvoeren met het ankergedeelte in het recursieve gedeelte. Het heeft echter geen middelen om cycli te detecteren, omdat cycli in de eerste plaats niet zijn gedefinieerd.

Zoals eerder vermeld, MySQL implementeert CTE niet 's helemaal niet (het implementeert niet HASH JOIN 's of MERGE JOIN s ook, alleen de geneste lussen, dus wees niet verbaasd).

Ironisch genoeg ontving ik vandaag een brief over dit onderwerp, dat ik in mijn blog zal behandelen.

Bijwerken:

Recursieve CTE 's in SQL Server zijn niet meer dan CONNECT BY in vermomming. Zie dit artikel in mijn blog voor schokkende details:

  • SQL Server:zijn de recursieve CTE's echt set-based?


  1. JQuery Ajax gebruiken om gegevens op te halen uit Mysql

  2. Hoe voeg ik een nieuwe kolom toe aan een tabel na de 2e of 3e kolom in de tabel met behulp van postgres?

  3. SQL AVG() voor beginners

  4. Sql-bestand in Windows importeren naar postgresql