SQL tree data struct(5): AdjList2NestedSet



/*
The organizational chart would look like this as a directed graph:

            Albert (1,12)
            /        /
          /            /
    Bert (2,3)    Chuck (4,11)
                   /    |   /
                 /      |     /
               /        |       /
             /          |         /
        Donna (5,6)  Eddie (7,8)  Fred (9,10)
*/

-- Transform recursion into non-recursion
-- Pre-Order tree traverse

-- 6. To convert an adjacency list model into a nested set model, use a push down stack algorithm.  Assume that we have these tables:

declare @tree table(emp varchar(30), boss varchar(30))
insert @tree
select 'Albert', NULL
union all select 'Bert', 'Albert'
union all select 'Chuck', 'Albert'
union all select 'Donna', 'Chuck'
union all select 'Eddie', 'Chuck'
union all select 'Fred', 'Chuck'

-- stack hold the info about nested_set
-- stack_index < 0 means the entry is pop out of the stack
declare @stack table(stack_index int, emp varchar(30), lft int, rgt int)

declare @counter int, @max_counter int, @current_top int
select @counter = 2, @max_counter = 2 * (select count(*) from @tree), @current_top = 1

insert @stack select 1, emp, 1, NULL from @tree where boss is null
delete from @tree where boss is null

select [@counter] = 1, [@current_top] = 1, * from @stack

-- check weather stack is empty (get rid of the variable @max_counter)
-- while exists (select * from @stack where stack_index > 0)
while @counter <= (@max_counter)
begin
    -- does the employee(stack_index = @current_top) has any subordinate ??
    if exists(select * from @tree t where (t.boss = (select emp from @stack where stack_index = @current_top)))
    begin
        -- push when top has subordinates and set lft value
        insert @stack select (@current_top+1), min(t.emp), @counter, NULL
            from @tree t where (t.boss = (select emp from @stack where stack_index = @current_top))
        -- delete the tree entry corresponding to the aforementioned subordinate
        delete from @tree where emp = (select emp from @stack where stack_index = @current_top + 1)

        select @current_top = @current_top + 1
    end
    else
    begin -- pop the stack and set rgt value
        update @stack set rgt = @counter, stack_index = -stack_index /*pop stack */ where stack_index = @current_top
        select @current_top = @current_top - 1
    end

    select [@counter] = @counter, [@current_top] = @current_top, * from @stack

    select @counter = @counter + 1
end
select * from @stack
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值