sql server中的递归函数

时间:2014-05-14 14:26:57

标签: sql sql-server tsql

我有两个表,第一个表是带有编号的父级ID,第二个表是父子关系。我需要找出第二个表中每一行的顶级表id。 例如

ID  Parent  Child TopLevel
66  4       5     1

请帮助Thks

表1:

TopParent
ID  No
1   1
2   5
3   6
4   7

表2:

ParentChild
ID  Parent   Child
66  4       5
71  4       6
72  4       7
82  7       2
84  1       4
85  5       7

1 个答案:

答案 0 :(得分:1)

我不太了解您示例中的数据。 TopParent表包含数字5,6和7,我认为它们是顶级父母,但这些数字在ParentChild中也显示为子项。此外,数字7在ParentChild表中显示为具有多个父项,并且虽然在这种特定情况下两个父母具有相同的最终父母,但是多个父母可能的事实表明存在记录的情况的可能性有多个顶级父母。

也就是说,如果您使用的是SQL Server 2005或更高版本,则可以使用common table expressions来编写递归查询。我写了一个简单的例子,希望能够接近你的情况,你将能够适应它。主要区别在于每个子节点只有一个父节点,并且我使用了一个在parent_id列中使用NULL来表示顶级父节点的表。

-- Here's some basic sample data similar to your ParentChild table.
declare @parentChild table (parent_id int, child_id int);
insert into @parentChild values
    (null, 1), (null, 2), (1, 3), (1, 4), (2, 5), (4, 6), (5, 7), (6, 8);

-- A common table expression allows you to write recursive queries.
with TopParentCTE as
(
    -- The base case: select those records which have no immediate parent.
    select child_id, parent_id
    from @parentChild
    where parent_id is null

    union all

    -- The recursive case: for records which have a parent, join to the CTE
    -- to get the next-highest parent. The recursion ends when this case no
    -- longer returns any results.
    select C.child_id, isnull(P.parent_id, P.child_id)
    from @parentChild C
        inner join TopParentCTE P on C.parent_id = P.child_id
)
select
    PC.child_id as [Child],
    PC.parent_id as [Immediate Parent],
    TP.parent_id as [Ultimate Parent]
from
    @parentChild PC
    inner join TopParentCTE TP on PC.child_id = TP.child_id
order by
    PC.child_id;