2012-04-05 10 views
6

ağaç tablo içinde veri kopyalamak Şimdi, bir başka düğüme bir kopyasını bir düğüm ve çocuğun ihtiyaç , kategoriPostgresql kolonlar <img src="https://i.stack.imgur.com/Vox2s.jpg" alt=""></p> <p><code>id</code>, <code>category</code>, <code>parent_id</code></p> <p>, ben ağaç yapısı ile tablo var

Benim girdi olacak .. ancak yeni kimliği ve PARENT_ID ile aynı olmalıdır node to copy & destination node to copy

Ben altında test görüntü dosyasına ağaç yapısını ..

i bunu bir işlev gerekir ..,

PostgreSQL sürümü 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

2 girişe sahip olan ve iş yapan işle bana yardımcı olur ... – MAHI

+0

Temel olarak bir alt ağacı klonlamak mı istiyorsunuz? Zor. Bunu düşünüyorum. – wildplasser

+0

evet zor .. pek çok işlevi denedim .. hayır .. – MAHI

cevap

5

(açıkladık PostgreSQL 8.4.3)

Aşağıdaki sorgu, düğüm 4'ün altındaki alt ağa yeni kimlikler atar (bkz. nextval) ve sonra da ebeveynlerin ebeveynlerinin yeni kimliklerine göllenme (bkz. LEFT JOIN). Eğer masaya geri takmak çok kolay, o sahip olduktan

, sadece alt ağaç kök yeniden bağlanmayı dikkatli olmak zorunda
new_id category new_parent_id 
------ -------- ------------- 
9  C4   
10  C5   9 
11  C6   9 
12  C7   10 

:

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 

Sonucu (Test verilerine) uygun ebeveyn ile (bu durumda, 8, COALESCE(new_parent_id, 8) bakınız):

: Bundan sonra

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 

, tablo, aşağıdaki verileri içerir

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

Bu harika. Tekrarlayan + bir sonraki kombinasyonun ekstra bir durum değişkenine ihtiyaç duymadan hile yapmasını beklemiyordum. Chapeau! – wildplasser

+0

@Branko teşekkürler, 9.1.2'de de işe yaradı .... – MAHI

+0

herkes bu konuda bana yardımcı olabilir (http://stackoverflow.com/questions/9077266/postgresql-update-tree-table-with-rows uçtan uca entegre-aynı tablo ile değişen-id-andparen) – MAHI

İlgili konular