Rekurzivni CTE jsou opravdu zvlastni. Rekl bych ze dost zasadne meni povahu SQL. Pridavaji do deklarativniho jazyka funkcionalni programovani. Prikladam jeden priklad pro Oracle:
with t_unique( s ) as ( select min(t1.s) from z t1 union all select (select min(t1.s) from z t1 where t1.s>t.s) from t_unique t where s is not null ) select * from t_unique where s is not null;
Tohle query najde nejmensi ID z tabulky, pak samo rebe rekurzivne zavola a hleda nejmensi ID vetsi nez to predchozi. Ve vysledku dostanete stejny vysledek jako pri
select distinct s from t1 order by 1;
Ale mnohem rychleji (alespon v mem pripade). Pro distinct se pouzije "INDEX FAST FULL SCAN" tzn. precte se cely segmet indexu (vcetne listu) a hodnoty se nahazeji do hash tabulky. Rekuzivni CTE skace v indexu nahoru a dolu az najde vsechny naindexovane hodnoty.
Prvni co cloveka napadne je proc to takhle Oracle nedela rovnou. Pri pohledu na explain plan vam dojde ze v pripade rekurze je planner uplne vedle a ze nedokaze predpovedet vubec nic. Pokud se s rekurznim CTE zacne prasit podobne jako se sablonami v C++ (Metaprogramming) budou muset dataabze prejit na planer jako maji VM v Prologu.
Této technice se říká loose index scan. Některé databáze jej mají implementovaný nativně - u jiných (včetně Postgresu) se musí použít workaround s CTE.
Už několik let nabízím téma diplomové práce - implementace loose index scanu do Postgresu.
Myslím si, že by to byla hezká diplomka - seznámení se s vnitřnostmi Postgresu - optimalizace - práce se statistikami, rozšíření exekutoru. Není to ale triviální a pravděpodobně to bude i hodně pracné. Na druhou stranu - po takové diplomce se člověk dostane mezi zdejší databázovou elitu (minimálně co se týče Postgresu).