给定子级或父级,从sql表中检索子级和父级

时间:2014-09-29 21:18:45

标签: sql sql-server

这是我的表:Test

id     OrderNo   parent_id
9      111      null     
4241   111       null     
5330   111       null     
1085   111       5330     
1087   111       1085     
2643   111       1087     

在上表中有父子关系。

我想要实现的是任何id(子或父)检索与之关联的所有行(整个集群)。例如,在上表中,如果我们将输入作为id = 1087,则应返回以下行:

id  
5330  
1085   
1087  
2643  

如果我们将父作为输入示例id = 5330

id  
5330  
1085  
1087  
2643  

如何编写一个查询或函数,其中包含Id并返回该集群中所有相关元素?

1 个答案:

答案 0 :(得分:1)

使用这个ddl:

CREATE TABLE orders
    (id int, OrderNo int, parent_id varchar(4))
;

INSERT INTO orders
    (id, OrderNo, parent_id)
VALUES
    (9, 111, NULL),
    (4241, 111, NULL),
    (5330, 111, NULL),
    (1085, 111, '5330'),
    (1087, 111, '1085'),
    (2643, 111, '1087')
;

因为你想开始'在任何地方,你真的需要两个递归查询。一个可以在更深层次或幼稚的情况下横列整理列表。方向,一个朝向更一般或父母的方向。节点

您可以尝试这样的事情

WITH childishCTE (orderNo, id, parent_id, [level]) as
(

    SELECT orderNo, id, parent_id, 0 as [level]
    FROM orders
-- --PUT YOUR ID HERE! --------------------------
    WHERE ID = 1087

    UNION ALL

    SELECT t.orderNo, t.id, t.parent_id, [level] + 1
        FROM orders t
            INNER JOIN childishCTE cte
                ON t.parent_id = cte.id

)
, parentalCTE as
(
    SELECT orderNo, id, parent_id, 0 as [level]
    FROM childishCTE
    WHERE Level = 0

    UNION ALL

    SELECT t.orderNo, t.id, t.parent_id, [level] - 1
        FROM orders t
            INNER JOIN parentalCTE cte
                ON t.id = cte.parent_id
)


SELECT id, level FROM childishCTE
UNION 
SELECT id, level FROM parentalCTE
ORDER BY level

请注意,您正在测试的ID不会在查询结尾处的where子句中。它进入了递归查询的一部分,称为“锚点”。