2011-08-05 9 views
7

मेरे पास PostgreSQL (PLPGSQL) में एक फ़ंक्शन है जो दो तत्वों वाली एक सरणी देता है। जब मैं एक का चयन करें बयान समारोह बुला चलाने के लिए, मैं (उम्मीद के रूप में) एक स्तंभ सरणी युक्त मिलती है:पोस्टग्रेएसक्यूएल कन्वर्ट एरे फ़ंक्शन से कॉलम पर वापस लौटा

[ 1 | 2 ] 
:

{1, 2} 

मैं सच में करना चाहते हैं क्या इन तत्वों को निकालने के लिए अपने स्वयं के कॉलम हो रहा है

मैं ने पाया है कि मैं कर सकते हैं:

SELECT (MyFunction())[1], (MyFunction())[2] 

लेकिन वह दो बार फ़ंक्शन को कॉल करने, इसलिए रन टाइम (इस समारोह एक बहुत समय लेने वाली कार्य है) दोहरीकरण। क्या इसे संभालने का कोई बेहतर तरीका है?


अद्यतन

यहाँ मैं क्या है के एक लगभग पूर्ण प्रतिकृति है:

SELECT table1.a, table1.b, table1.c, (MyFunction(table1.a, table1.b, table1.c))[1], 
(MyFunction(table1.a, table1.b, table1.c))[2] 
FROM table1 
INNER JOIN table2 using(b) 
WHERE ... GROUP BY table1.a, table1.b, table1.c; 

फिर, यह सरणी से दो कॉलम पैदा करता है, लेकिन मेरे समारोह दो बार कहा जाता है, जो मेरे रन टाइम को दोगुना करता है।

+0

मैं नोट करेंगे कि लौटने सरणी में तत्वों की संख्या हमेशा 2 ... – lightningmanic

+0

हो जाएगा प्राप्त परिणाम का आकार जाना जाता है, होना चाहिए आप एक सरणी वापस लौट रहे हो?यह शायद एक पंक्ति होनी चाहिए। क्या आपके पास उस पर प्रतिक्रिया करने की क्षमता है? – SingleNegationElimination

उत्तर

7

क्या आप उप-चयन का उपयोग कर सकते हैं?

postgres=# select ar[1], ar[2] from (select string_to_array('a b c', ' ') ar) as sq; 
ar | ar 
----+---- 
a | b 
(1 row) 

यह अभी भी आपको प्रत्येक कॉलम को स्पष्ट रूप से निकालने की आवश्यकता है (जैसा कि आप पहले से ही करते हैं)। यदि निकाले गए सरणी में अधिक तत्व हैं, तो वे खो जाएंगे, और यदि कम हैं, तो गायब कॉलम केवल NULL होंगे।

संपादित करें: मुझे लगता है कि मैं पूरी चीज़ को उप-चयन में लपेटूंगा;

SELECT subquery1.a, subquery1.b, subquery1.c, 
    myfunction_result[1], myfunction_result[2] 
FROM (SELECT table1.a, table1.b, table1.c, 
       MyFunction(table1.a, table1.b, table1.c) as myfunction_result 
     FROM table1 INNER JOIN table2 using(b) 
     WHERE ... GROUP BY table1.a, table1.b, table1.c 
) AS subquery1; 

भीतरी और बाहरी चयन ठीक से table1 संदर्भ सहसम्बन्धित हो जाएगा: भीतरी सबसिलेक्ट वांछित पंक्तियों, बाहरी के साथ वांछित कॉलम में आंतरिक क्वेरी पेश चयन उत्पन्न करता है।

+0

यह सामान्य "स्थानीय परिवर्तनीय" चालों में से एक है और इसे तब तक काम करना चाहिए जब तक सरणी में तत्वों की संख्या तय नहीं हो जाती है। –

+0

एकमात्र समस्या (और शायद मुझे पहले इसका उल्लेख करना चाहिए) यह है कि फ़ंक्शन एक ही क्वेरी स्तर के अन्य संबंधों पर निर्भर करता है। तो मैं "table_id" का चयन कर रहा हूं, और उसी आईडी को फ़ंक्शन में पास कर रहा हूं। – lightningmanic

+0

@ एमयू बहुत छोटा है: बिल्कुल सही नहीं है। संपादन देखें। – SingleNegationElimination

2

आप ऐसा नहीं कर सकते हैं। एक एकल सरणी कॉलम हो सकता है, उदाहरण के लिए, एक तत्व जिसमें तीन तत्व हैं और दूसरा पांच तत्व हैं। यदि आपने उन सरणी को अलग-अलग कॉलम में विस्तारित करने का प्रयास किया है, तो आप को परिणाम पंक्ति में दो पंक्तियों के साथ समाप्त कर देंगे, जिनमें कॉलम की अलग-अलग संख्याएं हैं और इसकी अनुमति नहीं है।

निकटतम बात उपलब्ध unnest है:

expand an array to a set of rows

लेकिन है कि आप वांछित कॉलम बल्कि पंक्तियों देता है।

2
select data[1] as id, data[2] as value from (SELECT 
string_to_array(rs,':') as data from unnest(string_to_array('1:234,2:400',',')) as rs) as foo 

यह क्योंकि इसके परिणाम स्वरूप:

id|Value 
-------- 
1 | 234 
2 | 400 
संबंधित मुद्दे