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,然后将其复制到某个位置的新主题ID,并保留下面的级别/结构

所以在我的例子中,我可以用 pos_id 1 指定主题 topic_id 2 ,它会创建

   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 是要插入副本的节点

4

2 回答 2

1

你可能想看看嵌套树集,我认为这对你的目的会更好。

这里很好的解释:

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

于 2013-07-26T11:01:30.390 回答
1

我认为你可以在一个声明中做到这一点。这是想法。

首先,为每个 id 扩展所有父母(在任何级别)的数据。这使用递归 CTE。

然后,回到原来的列表,只选择那些是2.

然后为该组中找到的每个 id 分配一个新的 id。以下查询获取该最大 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
于 2013-07-26T13:35:23.983 回答