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 にコピーして、その下のレベル/構造を保持したい

したがって、私の例では、トピック 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 は後にコピーを挿入するノードです

4

2 に答える 2

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 に答える