Выбрать всю родословную отца в SQL без WITH или WHILE

Можно ли выбрать все дочерние элементы родителя без рекурсивной системы как WITH или WHILE?

Структура является:

Father  Child

NULL    1
1       2
1       3
2       4
3       5
4       6
6       7

Я хочу, чтобы "childs" (вся генеалогия, childs of childs и т. Д. И т. Д.) Из 2, поэтому я хочу:

4, 6, 7

3 ответа

Да. Каждая рекурсивная функция имеет нерекурсивное решение:

Может ли каждая рекурсия быть преобразована в итерацию?

Некоторые другие ресурсы, которые могут быть полезны:

http://www.slideshare.net/rs_rs123/removal-of-recursion

http://www.refactoring.com/catalog/replaceRecursionWithIteration.html

Если вы точно знаете, на какую глубину вы хотите пойти, то, конечно, вам не нужно использовать рекурсию. Например, чтобы найти потомков первого уровня данного родителя, просто выполните:

select Child
from MyTable
where Father = 2

Даже если вам нужно несколько уровней (внуков, бабушек и дедушек и т. Д.), Если вы знаете, сколько уровней вы хотите, рекурсия вам строго не нужна, вы можете просто вложить несколько встроенных представлений, например:

select t1.Child
from MyTable t1
where t1.Father = 2
or t1.Father in (
    select t2.Child
    from MyTable t2
    where t2.Father = 2
)

(Это заводит детей и внуков)

Однако всякий раз, когда вы не знаете, сколько уровней дерева вверх / вниз вы хотите пройти (например, все потомки), рекурсия обычно является предпочтительной, а иногда и единственной возможностью (каламбур предназначен).

Мой собственный подход - делать один запрос на поколение.

Таким образом, вы начнете с идентификатора ребенка. Для первого поколения выберите всех людей, чей ребенок имеет данный идентификатор. Для второго поколения выберите всех людей, чей ребенок имеет идентификатор в первом поколении. И так далее.

Это значительно уменьшает количество запросов по сравнению с рекурсивным поиском родителей для каждого человека, и это чрезвычайно быстро в тестах, которые я проводил на sqlite, для генеалогии 22 поколений.

Другие вопросы по тегам