SQL-запрос CTE повторяется в двух направлениях

Я использую Postgres 9.1, и у меня есть таблица с иерархией генеалогического дерева. Эта таблица называется родительской и содержит два внешних ключа: один для родителя и один для дочернего элемента в отношении. Следующий SQL-запрос (по большей части украденный из документации Postgres) работает, но проходит по дереву как вверх, так и вниз:

with recursive temp(child, parent, depth, path, cycle) as
        (select child, parent, 1, array[child], false
         from parents
         where parent = 149

         union all

         select parents.child, parents.parent, temp.depth + 1, path || parents.child, parents.child = any(path)
         from temp, parents
         where parents.child = temp.parent)
    select distinct c1.name as child_name, c2.name as parent_name
    from temp
    join people c1 on temp.child = c1.id
    join people c2 on temp.parent = c2.id;

Parent 149 является корневым узлом обхода.

На выходе имеется одно поколение детей и все поколения предков из 149. В идеале запрос должен спускаться по генеалогическому дереву и не иметь поколений предков.


person ldrg    schedule 11.07.2012    source источник
comment
Может быть, изменить where parents.child = temp.parent на where parents.parent = temp.child?   -  person wildplasser    schedule 11.07.2012


Ответы (1)


Отказ от ответственности: этот ответ был принят до того, как я понял, что @wildplasser имеет уже предлагали то же самое в своем комментарии к вопросу. (Извините, я не хотел воровать чужие идеи.)

Если вы хотите построить только поколения, происходящие от данного родителя, вы должны изменить это условие

parents.child = temp.parent

к этому

temp.child = parents.parent

потому что именно temp дочерние элементы должны рассматриваться как родители (т. е. сопоставляться с parents.parent) на следующей итерации.

person Andriy M    schedule 11.07.2012
comment
По сути, это копия комментария wildplasser без указания авторства. - person Erwin Brandstetter; 11.07.2012
comment
Ах, это неловко. Хотел бы я увидеть это в то время! Я имею в виду, я понимаю, что трудно поверить, что я этого не делал. Думаю, я просто добавлю кредит сейчас. - person Andriy M; 11.07.2012
comment
Ничего страшного. В любом случае это слишком тривиально, чтобы называться ответом ;-) - person wildplasser; 11.07.2012
comment
@wildplasser: Спасибо, вы очень любезны. Но я хотел бы, чтобы вы знали, что, тривиально или нет, я все равно попытался бы убедить вас опубликовать свой комментарий в качестве ответа. :) - person Andriy M; 11.07.2012