От документацията за CONNECT_BY_ISCYCLE
:
CONNECT_BY_ISCYCLE
псевдоколона връща1
ако текущият ред има дете, което е и негов предшественик
и това на CYCLE
:
Счита се, че ред образува цикъл, ако един от неговите предшествещи редове има същите стойности за колоните на цикъла.
Във вашия пример, ред 2
има дете, което също е негов предшественик, но неговият id
все още не е върнат.
С други думи, CONNECT_BY_ISCYCLE
проверявадецата (които тепърва ще бъдат върнати), докато CYCLE
проверява текущия ред (което вече е върнато).
CONNECT BY
е базиран на ред, докато рекурсивният CTE
's са базирани на набори.
Имайте предвид, че документацията на Oracle за CYCLE
споменава "ред с предшественици". Въпреки това, най-общо казано, няма концепция за "ред-предшественик" в рекурсивния CTE
. Това е операция, базирана на набор, която може да даде резултати напълно извън дървото. Най-общо казано, анкерната част и рекурсивната част могат дори да използват различните таблици.
Тъй като рекурсивният CTE
's са обикновено използва се за изграждане на йерархични дървета, Oracle
реши да добави проверка на цикъла. Но поради базирания на множество начин рекурсивният CTE
's operation, обикновено е невъзможно да се каже дали следващата стъпка ще генерира цикъл или не, тъй като без ясно определение на цикъла „ред-предшественик“ също не може да се дефинира условието на цикъла.
За да изпълним „следващата“ стъпка, целият „текущ“ набор трябва да е наличен, но за да генерираме всеки ред от текущия набор (който включва колоната на цикъла), просто трябва да имаме резултатите от операцията „следваща“.
Не е проблем, ако текущият набор винаги се състои от един ред (като в CONNECT BY
), но е проблем, ако рекурсивната операция е дефинирана върху множество като цяло.
Не разгледах Oracle 11
все още, но SQL Server
прилага рекурсивен CTE
е като просто скриете CONNECT BY
зад тях, което изисква поставянето на множество ограничения (всички от които на практика забраняват всички операции, базирани на набори).
PostgreSQL
Реализацията на 's, от друга страна, е наистина базирана на набори:можете да извършвате всяка операция с анкерната част в рекурсивната част. Той обаче няма никакви средства за откриване на цикли, тъй като циклите не са дефинирани на първо място.
Както беше споменато по-горе, MySQL
не прилага CTE
's изобщо (не прилага HASH JOIN
's или MERGE JOIN
както и само вложените цикли, така че не се изненадвайте много).
По ирония на съдбата днес получих писмо точно по тази тема, която ще разгледам в моя блог.
Актуализация:
Рекурсивен CTE
е в SQL Server
са не повече от CONNECT BY
под прикритие. Вижте тази статия в моя блог за шокиращи подробности:
- SQL сървър:рекурсивните CTE наистина ли са базирани на множество?