2012-04-05 11 views
6

मैं वृक्ष संरचना के साथ तालिका है के भीतर डेटा की प्रतिलिपि, कॉलम id, category, parent_idPostgresql पेड़ तालिका

हैं अब मैं एक प्रति एक नोड और उसके बच्चे की एक अन्य नोड के लिए की जरूरत है, जबकि को कॉपी , श्रेणी के समान होना चाहिए, लेकिन नए आईडी और 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) 
+0

मुझे ऐसे फ़ंक्शन के साथ सहायता करें जो 2 इनपुट प्राप्त करें और नौकरी करें ... – MAHI

+0

तो मूल रूप से आप एक उप-समूह क्लोन करना चाहते हैं? कठिन। मैं इस पर सोच रहा हूँ। – wildplasser

+0

हाँ इसकी कड़ी मेहनत .. मैंने कई फ़ंक्शन के साथ प्रयास किया है .. कोई उपयोग नहीं .. – MAHI

उत्तर

5

(के तहत परीक्षण किया समझा दिया है PostgreSQL 8.4.3)

निम्न क्वेरी नोड 4 के तहत उप-पेड़ में नई आईडी निर्दिष्ट करती है (nextval देखें) और फिर कोर माता-पिता के माता-पिता (LEFT JOIN देखें) पर नए आईडी को तालाब करना।

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 

परिणाम (अपने परीक्षण के आंकड़ों पर) उचित माता पिता के साथ (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 
+0

यह शानदार है। मुझे उम्मीद नहीं थी कि रिकर्सिव + अगली कॉम्बो एक अतिरिक्त स्टेट वैरिएबल की आवश्यकता के बिना चाल कर सकती है। Chapeau! – wildplasser

+0

@ ब्रैंको धन्यवाद, यह 9.1.2 में भी काम करता है .... – MAHI

+0

क्या कोई मेरी मदद कर सकता है [http://]] http://stackoverflow.com/questions/9077266/postgresql-update-tree-table-with-rows -से-एक ही मेज-दर-बदलते-आईडी-andparen) – MAHI