SQL Server, как получить все узлы от любого потомка до предка в дереве? - PullRequest
3 голосов
/ 19 апреля 2011

В этот ответ я спросил, как получить все подузлы, а также иметь ссылку на корневой узел.Теперь я понимаю, что мне нужно и обратное:

Я хочу иметь все узлы и всех родителей.

, поэтому в этом простом дереве:

1 - 2 - 3

    L - 4 - 5

        L - 6

7 - 8

Iхотел бы иметь

1 1;
2 2;
2 1;
3 3;
3 2;
3 1;
4 4;
4 2;
4 1;
5 5;
5 4;
5 2;
5 1;
6 6;
6 4;
6 2;
6 1;
7 7;
8 8;
8 7;

(порядок не важен)

Это был запрос для получения противоположности (от parent get все дочерние элементы).Я пытался поиграть с ним, но не смог найти решение.Не могли бы вы предложить?

-- get all childs of all parents
WITH    q AS
        (
        SELECT  ID_CUSTOMER, ID_CUSTOMER AS root_customer
        FROM    CUSTOMERS c
        UNION ALL
        SELECT  c.ID_CUSTOMER, q.root_customer
        FROM    q
        JOIN    CUSTOMERS c 
        ON      c.ID_PARENT_CUSTOMER = q.ID_CUSTOMER
        )
SELECT  *
FROM    q

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

Этот запрос создает transitive closure списка смежности: список всех пар предок-потомок.

Так как он вернет всех потомков для каждого предка, верно и обратное: для каждого потомка онвернет всех своих предков.

Таким образом, этот запрос возвращает все возможные комбинации, независимо от порядка обхода: не имеет значения, являетесь ли вы связью родителей с детьми или наоборот.

Давайте проверим это:

WITH    customers (id_customer, id_parent_customer) AS
        (
        SELECT  *
        FROM    (
                VALUES  (1, NULL),
                        (2, 1),
                        (3, 2),
                        (4, 2),
                        (5, 4),
                        (6, 4),
                        (7, NULL),
                        (8, 7)
                ) t (a, b)
        ),
        q AS
        (
        SELECT  ID_CUSTOMER, ID_CUSTOMER AS root_customer
        FROM    CUSTOMERS c
        UNION ALL
        SELECT  c.ID_CUSTOMER, q.root_customer
        FROM    q
        JOIN    CUSTOMERS c 
        ON      c.ID_PARENT_CUSTOMER = q.ID_CUSTOMER
        )
SELECT  *
FROM    q
ORDER BY
        id_customer, root_customer DESC
0 голосов
/ 19 апреля 2011
with q (
select id_customer, id_parent_customer from customers
union all
select id_customer, id_parent_customer from customers
join q on customers.id_parent_customer = q.id_customer
) select * from q
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...