问题描述
我的表具有树结构,列为 id
,类别
, parent_id
I have table with tree structure, columns are id
, category
, parent_id
现在我需要将一个节点及其子节点复制到另一个节点,在复制时,类别必须相同,但是具有新的id和parent_id.
Now I need a copy a node and its child's to a another node, while copying, the category must be same, but with new id and parent_id..
我的输入将是要复制的节点
&要复制的目标节点
My input will be node to copy
& destination node to copy
我已经解释了图像文件中的树结构.
I have explained the tree structure in the image file..
我需要一个函数来做..,
i need a function to do so..,
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)
推荐答案
(在PostgreSQL 8.4.3下测试)
以下查询将新ID分配给节点4下的子树(请参见 nextval
),然后找到相应的新父母父母的ID(请参见左键
).
The following query assigns new IDs to the sub-tree under node 4 (see the nextval
) and then finds the corresponding new IDs of parents (see the 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
结果(关于您的测试数据):
Result (on your test data):
new_id category new_parent_id
------ -------- -------------
9 C4
10 C5 9
11 C6 9
12 C7 10
一旦有了它,就很容易将其插入到表中,只需小心地将子树根与适当的父级重新连接(在这种情况下为8,请参见 COALESCE(new_parent_id,8)
):
Once you have that, it's easy to insert it back to the table, you just have to be careful to reconnect the sub-tree root with the appropriate parent (8 in this case, see the 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
此后,该表包含以下数据:
After that, the table contains the following data:
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
这篇关于PostgreSQL复制树表中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!