sql server如何检索树中从任何子节点到祖先的所有节点?

发布于 2024-11-01 23:53:12 字数 843 浏览 0 评论 0原文

这个答案中,我问如何获取所有子节点并且还具有对根节点的引用。现在我意识到我还需要相反的东西:

我想要拥有所有节点和所有父节点。

所以在这个简单的树中:

1 - 2 - 3

    L - 4 - 5

        L - 6

7 - 8

我想要

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;

(顺序并不重要)

这是获取相反的查询(从父级获取所有子级)。我尝试玩它但找不到解决方案。你能建议一下吗?

-- 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

In this answer i asked how to get all subnodes and also having a reference to the root node. Now I realize that I need also the contrary:

I want to have all the nodes and all the parents.

so in this simple tree:

1 - 2 - 3

    L - 4 - 5

        L - 6

7 - 8

I would like to have

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;

(the order is not important)

This was the query to obtain the opposite (from parent get all childs). I tried to play with it but couldn't find the solution. Could you suggest?

-- 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北城孤痞 2024-11-08 23:53:12

此查询构建邻接列表的传递闭包:所有祖先-后代对的列表。

由于它将返回每个祖先的所有后代,因此反之亦然:对于每个后代,它将返回其所有祖先。

因此,无论遍历顺序如何,这个查询都会返回所有可能的组合:无论您是将父母连接到孩子还是将父母连接到孩子,都没有关系。

我们来测试一下:

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

This query builds a transitive closure of the adjacency list: a list of all ancestor-descendant pairs.

Since it will return all descendants for every ancestor, the opposite is also true: for each descendant it will return all its ancestors.

So this very query does return all possible combinations, regardless of the traversal order: it does not matter whether you are connection parents to children or the other way around.

Let's test it:

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
他是夢罘是命 2024-11-08 23:53:12
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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文