# n is normally an integer but can be anything create or replace function sum_digits(n) as ( regexp_extract_all(n::VARCHAR, '.') .list_transform( x -> (ascii(x) - 48) % 10) .list_sum() ); # n should be an integer create or replace function digital_root(n) as table ( with recursive cte as ( select 0 as ix, n as sum union all select ix+1, sum_digits(sum) from cte where length(sum::VARCHAR) > 1 ) select last(ix order by ix) as persistence, last(sum order by ix) as "digital root", from cte ); ## Examples: from (select unnest(range(0, 4)) as i, unnest([627615, 39390, 588225, 393900588225]) as n), (from digital_root(n)) order by i;