在SQL Server 2005中需要有关递归的帮助

时间:2009-08-03 14:32:50

标签: sql-server sql-server-2005

我在表中表示一棵树,我需要能够获得特定元素的根节点(TOP ID)。根节点始终具有ParentID null。例如,如果表格如下所示:

ID   ParentID
1   null
2   null
3   null
4   2
5   1
6   2
7   6
8   4
9   8
10  6

ID=10时,TOP ID = 2; ID=9时,TOP ID = 3;等等。是否可以编写SQL服务器函数,在给定TOP ID时返回ID

6 个答案:

答案 0 :(得分:3)

这是一个来自我的sproc的递归示例,它将为给定给sproc的任何给定ID(@ID)找到Parent(父ID = null)。你正在寻找这个吗?

    WITH recurseUp (ID, ParentID)
    AS
    (
        SELECT ID, ParentID
        FROM myTable
        WHERE ID = @ID 
        UNION ALL
        SELECT b.ID, b.ParentID
        FROM recurseUp a JOIN myTable b 
        ON (a.ParentID = b.ID)
    )
SELECT ID FROM recurseUP WHERE ParentID is null

答案 1 :(得分:2)

MSDN有一组很好的使用Common Table Expressions来编写递归查询的示例。在SQL Server 2005之前执行这些操作是非常困难的(现在处理旧的Server 2000应用程序中的确切问题)。

答案 2 :(得分:1)

SQL 2003之前的SQL中的递归(即SQL Server 2000)有点难看;对于树中的每个级别,您需要将单独的连接语句写回原始表。如果您的层次结构中的级别数量是固定的,您可以编写类似的内容。

create table #Hell (
parent int,
id int,
name varchar(30)
)

insert into #Hell values (NULL, 1, 'The Boss')
insert into #Hell values (1, 2, 'The Boss'' PA')
insert into #Hell values (1, 3, 'Production Director')
insert into #Hell values (3, 4, 'Jim''l Fixit')


select * from #Hell H1
inner join #Hell H2
ON H1.id=H2.parent
inner join #Hell H3
ON H2.id=H3.parent
WHERE H3.Id=4  --Find the boss for Jim

drop table #Hell

幸运的是,SQL Server 2005有一个 with 公用表表达式,允许非常容易地编写递归操作。请参阅http://www.4guysfromrolla.com/webtech/071906-1.shtml

您还应该了解在数据库中表示树的各种方法。从这个演示文稿http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back

中查看SQL中的Trees上的幻灯片

答案 3 :(得分:0)

MSDN上升this article,这很可能比你可能以我们允许的格式更好地解释它。

答案 4 :(得分:0)

这是可能的,但我知道的唯一方法是使用CURSOR和递归存储过程。从绩效的角度来看,这是一种非常糟糕的做事方式(通常)。如果可能,您可能需要考虑在移动时通过代码保持更新的额外根父节点的成本。

答案 5 :(得分:0)

WITH    q AS
        (
        SELECT  id, parentID
        FROM    mytable
        WHERE   id = 10
        UNION ALL
        SELECT  mytable.id, mytable.parentid
        FROM    q
        JOIN    mytable
        ON      mytable.parentId = q.id
        )
SELECT  *
FROM    q
WHERE   parentID IS NULL