Мне было легче:
1) создать функцию, которая будет проверять, находится ли элемент где-либо в родительской иерархии другого. Что-то вроде этого (я не буду писать функцию, сделаю ее с WHILE DO):
is_related(id, parent_id);
в вашем примере
is_related(21, 19) == 1;
is_related(20, 19) == 1;
is_related(21, 18) == 0;
2) используйте подвыбор, что-то например:
select ...
from table t
join table pt on pt.id in (select i.id from table i where is_related(t.id,i.id));
Монадные трансформаторы не очень математически приятны. Тем не менее, мы можем получить хорошие (со) продукты из бесплатных монад и, в более общем смысле, идеальные монады: см. «Копродукции идеальных монад» Гани и Уусталу: http://citeseerx.ist.psu.edu/viewdoc/ Резюме? DOI = 10.1.1.4.2698