2012-04-05 33 views
6

Tôi có bảng với cấu trúc cây, cột id, category, parent_idPostgreSQL sao chép dữ liệu trong bảng cây

Bây giờ tôi cần một bản sao một nút và con của nó đối với một nút khác, khi sao chép , hạng mục phải giống nhau, nhưng với id mới và PARENT_ID ..

đầu vào của tôi sẽ là node to copy & destination node to copy

tôi đã giới thiệu các cấu trúc cây trong file ảnh ..

tôi cần một chức năng để làm như vậy ..,

phiên bản 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) 
+0

giúp tôi với chức năng nhận 2 đầu vào và thực hiện công việc ... – MAHI

+0

Vì vậy, về cơ bản bạn muốn sao chép một cây con? Cứng. Tôi đang nghĩ về nó. – wildplasser

+0

có độ cứng của nó .. tôi đã thử với nhiều chức năng .. không sử dụng .. – MAHI

Trả lời

5

(thử nghiệm dưới PostgreSQL 8.4.3)

Truy vấn sau gán ID mới cho cây con dưới nút 4 (xem nextval) và sau đó tìm các sửa ponding ID mới của cha mẹ (xem 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 

quả (trên dữ liệu thử nghiệm của bạn):

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

khi bạn đã có, thật dễ dàng để chèn nó trở lại để bàn, bạn chỉ cần phải cẩn thận để kết nối lại các gốc cây con với phụ huynh thích hợp (8 trong trường hợp này, vui lòng xem 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 

sau đó, bảng chứa dữ liệu sau:

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 
+0

Điều này thật tuyệt vời. Tôi đã không mong đợi các combo đệ quy + tiếp theo có thể làm các trick mà không cần một biến trạng thái thêm. Chapeau! – wildplasser

+0

@Branko cảm ơn, nó hoạt động tốt trong 9.1.2 .... – MAHI

+0

bất cứ ai có thể giúp tôi với [this] (http://stackoverflow.com/questions/9077266/postgresql-update-tree-table-with-rows -from-same-table-by-changing-id-andparen) – MAHI

Các vấn đề liên quan