Recursion in SQL Explained Visually (2020)
denis-lukichev.medium.com
denis-lukichev.medium.com
https://gist.github.com/bokwoon95/4fd34a78e72b2935e78ec0f40e...
https://www.postgresql.org/docs/current/ltree.html
"This module implements a data type ltree for representing labels of data stored in a hierarchical tree-like structure. Extensive facilities for searching through label trees are provided."Quickest explanation: each node has two numbers: left and right (or low/high). All children under the node have numbers between left and right. So, querying an entire sub-branch:
select child.* from Nodes as parent, Nodes as child where child.lft between parent.lft and parent.rgt;
It is used to extract an explained query from a plan table.
It does seem to be much easier than a common table expression.
How about we don't, and think about queries as the algebraic relations that they are?
I always found this explanation of SQL (and SQL-like) recursion much more reasonable than efforts to shoehorn SQL into an iterative, functional box: https://core.ac.uk/download/pdf/11454271.pdf
Quite powerful stuff, both in the results it can produce and in the resources it can drain from the server.
Besides the typical "linked-list" queries, I used this to split a comma-separated column value into separate rows, as our DB server did not have that as a built-in function. Not pretty, but it did the job.
with recursive lst (subidx, elm, input_str) as (
( -- initial row
select nullif(charindex(',', input_str), 0) as subidx, coalesce(substr(input_str, 1, subidx-1), input_str) as elm, input_col as input_str
from (select 'abc, d, ef, ghj' as input_col) x -- replace subquery with something useful
)
union all
( -- recursive
select nullif(charindex(',', substr(input_str, subidx+1)), 0)+subidx as next_subidx, substr(input_str, subidx+1, coalesce(next_subidx-1-subidx, length(input_str))) as next_elm, input_str as next_input_str
from lst
where subidx < length(input_str)
)
)
select trim(elm) from lst