H2 рекурсия

Н2 СУБД, несмотря на свой размер (меньше 2 Мб), имеет поддержку CTE и возможность делать рекурсивный обход, при этом требует только наличие Java машины.

H2 СУБД удобно использовать для своих целей, так как она очень легковесная, поддерживает очень много “плюшек” (в том числе и интеграция с PDI, которую можно почитать по ссылкам внизу).

Теперь немного поговорим о рекурсии и приведем иерархическую таблицу в плоский вид.

create table test_rec (
 id int,
 pid int,
 descr varchar(256)
);
insert into test_rec values (1,NULL, 'Россия');
insert into test_rec values (2,1, 'Москва');
insert into test_rec values (3,2, 'Головной');
insert into test_rec values (4,1, 'Приморье');
insert into test_rec values (5,4, 'Офис 1');
insert into test_rec values (6,4, 'Офис 2');

Рекурсивно обходим:

with recursive tree (id, pid, levels, Descr, group_tree) as
(
	 select id,  pid, 1 as levels,   Descr,  '#\1#' || Descr || '#/1#' as group_tree
	 from test_rec
   	 where pid is null
   	 union all
   	 select  test_rec.id,  test_rec.pid, levels + 1 , test_rec.Descr , tree.group_tree  || '#\' || levels + 1 || '#'||  test_rec.Descr || '#/' || levels + 1 || '#'
   	 from tree
	 	inner join test_rec  on tree.id = test_rec.pid
)
select  id,
       	pid,
     	levels,
     	Descr as base_group,
      	SUBSTR( group_tree, LOCATE('#\1#', group_tree)+4, LOCATE('#/1#', group_tree)-LOCATE('#\1#', group_tree)-4) as group_1,
      	SUBSTR( group_tree, LOCATE('#\2#', group_tree)+4, LOCATE('#/2#', group_tree)-LOCATE('#\2#', group_tree)-4) as group_2,
      	SUBSTR( group_tree, LOCATE('#\3#', group_tree)+4, LOCATE('#/3#', group_tree)-LOCATE('#\3#', group_tree)-4) as group_3
from tree
order by 1;

Результат работы

h2 rec

Ссылки на материалы:

  1. SQL Grammar http://www.h2database.com/html/grammar.html
  2. H2 https://ru.wikipedia.org/wiki/H2
  3. Using an on-demand in-memory SQL database in PDI http://type-exit.org/adventures-with-open-source-bi/2011/01/using-an-on-demand-in-memory-sql-database-in-pdi/