Выбрать всю родословную отца в 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 поколений.