2013-07-26 101 views
1

我有一個相鄰列表層次結構模型,構成了主題結構如何在相鄰列表

ID Parent_Id Topic_Name 
    1 Null  Topic 1 
    2 Null  Topic 2 
    3 2   Topic 3 
    4 3    Topic 4 
    5 2   Topic 5 
    6 Null  Topic 6 

我要指定一個主題ID,然後在複製到一個新的話題身份證複印件節點的孩子一定的位置,並保留水平/結構之下

所以在我的例子,我可以指定主題topic_id 2 pos_id 1,它會創建

ID Parent_Id Topic_Name 
    1 Null  Topic 1 
    7 Null  Topic 2 
    8 7   Topic 3 
    9 8    Topic 4 
    10 7   Topic 5 
    2 Null  Topic 2 
    3 2   Topic 3 
    4 3    Topic 4 
    5 2   Topic 5 
    6 Null  Topic 6 

topic_id是一個節點複製和pos_id是插入複印後

自動編號是針對該ID的節點,但我不能保證的子節點將永遠是下一個ID號了從父。

topic_id是一個節點複製和pos_id是後

+1

那麼你面臨什麼問題?你有什麼嘗試? –

+0

哪個版本? –

+0

是否要複製一個主題(包括孩子)或想要更改某個主題的父級? –

回答

1

我認爲你可以在一個聲明中做到這一點。這是主意。

首先,擴大每個ID爲所有家長的數據(任何級別)。這使用遞歸CTE。

然後,再回到原來的列表,並只選擇那些誰是2後裔。

然後分配一個新的ID,以每本組中發現的IDS。以下查詢獲取該最大ID並向其添加row_number()常量。

然後,在樹的每個記錄,查找記錄中的新的ID,然後插入結果。

下面的查詢採取了這種辦法。我沒有測試過它:

with Parents as (
     select id, parent_id, 1 as level 
     from AdjList al 
     union all 
     select cte.id, cte.Parent_id, level+1 
     from AdjList al join 
      cte 
      on cte.Parent_id = al.id 
    ), 
    LookingFor as (
     select * 
     from AdjList 
     where id in (select id from Parents where id = 2) 
    ), 
    NewIds as (
     select id, const.maxid + ROW_NUMBER() over (order by (select NULL)) as newid 
     from (select distinct id 
      from LookingFor 
      ) t cross join 
      (select MAX(id) as maxid, from AdjList) const 
    ) 
insert into AdjList(Id, Parent_id, Topic_Name) 
    select ni1.newid, coalesce(ni2.NEWID, 1), lf.Topic_Name 
    from LookingFor lf left outer join 
     NewIds ni1 
     on lf.id = ni1.id left outer join 
     NewIds ni2 
     on lf.Parent_Id = ni2.id 
    where ni1.newid is not null 
1

你可能想看看嵌套Treesets至極將是你的目的,我認爲更好的方式來插入副本的節點。

大在這裏的解釋:

http://en.wikipedia.org/wiki/Nested_set_model

+0

我確實看過模型,但有性能問題。使用插入和重新排序,必須爲每條記錄更新左右值。在1米以上的桌子上,這是一個痛苦的過程 – totalitarian