WITH compute_fib(previous, curr) AS ( SELECT 0, 1 FROM dual UNION ALL SELECT curr, previous+curr FROM compute_fib WHERE curr < 60 ) -- Oracles endless loop protection CYCLE previous, curr SET is_cycle TO '1' DEFAULT 'Y' SELECT previous FROM compute_fib;
For those of you who wonder what this CYCLE expression stands for this is a good summary:
When a node is encountered for the second time, it will be included in the result set, its column value IS_CYCLE (a new column [...] with the statement above) is set to Y and the recursion stops then and there – so there will not be a second iteration starting at this node. Note however that any node where a cycle starts is included in the result set twice. [source]
This example is also introducing a nice aspect of the WITH clause I wasn't aware of so far - you can provide the column names of the subquery as arguments. See those two snippets for what I mean:
-- this is how I used to name the columns of a subquery. -- the first SELECT of a UNION also defines the column names WITH old_way AS ( SELECT 1 AS first_row, 2 AS second_row FROM dual UNION ALL SELECT 3, 4 FROM dual ) SELECT * FROM old_way; -- this is much clearer way where the subquery -- explicitly defines the column names WITH new_way(first_row, second_row) AS ( SELECT 1, 2 FROM dual UNION ALL SELECT 3, 4 FROM dual ) SELECT * FROM new_way;
Keine Kommentare:
Kommentar veröffentlichen