SQL SELECT, чтобы найти циклические ссылки в отце-организованном дереве? - PullRequest
6 голосов
/ 27 апреля 2011

"Fun" с циклическими ссылками:

Предположим, у меня есть таблица ELEMENTS, которая содержит иерархию элементов, смоделированных с помощью идентификатора отца.

Поле идентификатора отца для корня равно нулю.

Все остальные записи имеют ненулевой идентификатор отца с первичным ключом (ID) родительского элемента (с автопоследовательностью).

Например, используя

SELECT *
FROM Elements
WHERE FATHER_ID not in (SELECT ID FROM Elements)

Я могу найти все элементы, которые имеют недопустимые ссылки на отцов (FATHER_ID не является внешним ключом, давайте предположим, что в этом примере).

Но как мне найти элементы, которые имеютдействительная ссылка на отца, НО, чья цепочка ссылок на отца не заканчивается в корне? Я думаю, что это может произойти только для циклических ссылок, например, A является отцом B, но B также является отцом A.Такое «поддерево» не связано с корнем и, следовательно, не является частью основного дерева. Я хочу найти такие поддеревья.

Конечно, я ищу запрос, который доставляет те элементы, которые приводят к циклической ссылке, независимо от длины цепочки ссылок.

Возможно ли это в SQL или мне нужно итеративное решение?

1 Ответ

5 голосов
/ 27 апреля 2011
SELECT  n.*, CONNECT_BY_ROOT(id), level
FROM    elements n
START WITH
        id IN
        (
        SELECT  MIN(id)
        FROM    (
                SELECT  id, CONNECT_BY_ROOT(id) AS root
                FROM    elements
                START WITH
                        id IN
                        (
                        SELECT  id
                        FROM    elements n
                        WHERE   CONNECT_BY_ISCYCLE = 1
                        CONNECT BY NOCYCLE
                                father_id = PRIOR id
                        )
                CONNECT BY NOCYCLE
                        id = PRIOR father_id
                )
        GROUP BY
                root
        )
CONNECT BY NOCYCLE
        id = PRIOR father_id

Вы можете прочитать эту статью:

...