6

ツリー構造のテーブルがあり、列はid、、、categoryparent_id

ここで、ノードとその子を別のノードにコピーする必要があります。コピー中、カテゴリは同じである必要がありますが、新しい ID と parent_id が必要です。

私の入力はnode to copy&になりますdestination node to copy

画像ファイルのツリー構造について説明しました。

そのための関数が必要です..、

PostgreSQL バージョン 9.1.2

  Column   |  Type   |                    Modifiers                    
-----------+---------+-------------------------------------------------
 id        | integer | not null default nextval('t1_id_seq'::regclass)
 category  | text    | 
 parent_id | integer | 
Indexes:
    "t1_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "fk_t1_1" FOREIGN KEY (parent_id) REFERENCES t1(id)
Referenced by:
    TABLE "t1" CONSTRAINT "fk_t1_1" FOREIGN KEY (parent_id) REFERENCES t1(id)
4

1 に答える 1

8

(PostgreSQL 8.4.3 でテスト済み)

次のクエリは、ノード 4 の下のサブツリーに新しい ID を割り当て ( を参照nextval)、対応する親の新しい ID を検索します ( を参照LEFT JOIN)。

WITH RECURSIVE CTE AS (
    SELECT *, nextval('t1_id_seq') new_id FROM t1 WHERE id = 4
    UNION ALL
    SELECT t1.*, nextval('t1_id_seq') new_id FROM CTE JOIN t1 ON CTE.id = t1.parent_id
)
SELECT C1.new_id, C1.category, C2.new_id new_parent_id
FROM CTE C1 LEFT JOIN CTE C2 ON C1.parent_id = C2.id

結果 (テスト データ):

new_id  category    new_parent_id
------  --------    -------------
9       C4          
10      C5          9
11      C6          9
12      C7          10

それができたら、それをテーブルに挿入するのは簡単です。サブツリー ルートを適切な親 (この場合は 8、 を参照COALESCE(new_parent_id, 8))に再接続するように注意する必要があります。

INSERT INTO t1
SELECT new_id, category, COALESCE(new_parent_id, 8) FROM (
    WITH RECURSIVE CTE AS (
        SELECT *, nextval('t1_id_seq') new_id FROM t1 WHERE id = 4
        UNION ALL
        SELECT t1.*, nextval('t1_id_seq') new_id FROM CTE JOIN t1 ON CTE.id = t1.parent_id
    )
    SELECT C1.new_id, C1.category, C2.new_id new_parent_id
    FROM CTE C1 LEFT JOIN CTE C2 ON C1.parent_id = C2.id
) Q1

その後、テーブルには次のデータが含まれます。

new_id  category    new_parent_id
------  --------    -------------
1       C1
2       C2          1
3       C3          1
4       C4          2
5       C5          4
6       C6          4
7       C7          5
8       C8          3
9       C4          8
10      C5          9
11      C6          9
12      C7          10
于 2012-04-05T12:09:55.797 に答える