我有一个构成主题结构的相邻列表层次结构模型
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是在
之后插入副本的节点答案 0 :(得分:1)
答案 1 :(得分: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