2010-04-01 14 views
169

मेरे पास एक टेबल है और मैं प्रति पंक्ति एक पंक्ति को फ़ील्ड मानों के साथ खींचना चाहता हूं।पोस्टग्रेस्क्ल GROUP_CONCAT समतुल्य?

मेरी तालिका में, उदाहरण के लिए, मैं इस है:

TM67 | 4 | 32556 
TM67 | 9 | 98200 
TM67 | 72 | 22300 
TM99 | 2 | 23009 
TM99 | 3 | 11200 

और मैं करने के लिए उत्पादन करना चाहते हैं:

TM67 | 4,9,72 | 32556,98200,22300 
TM99 | 2,3 | 23009,11200 

MySQL में मैं एकीकृत फ़ंक्शन GROUP_CONCAT उपयोग करने में सक्षम था, लेकिन यह यहां काम नहीं कर रहा है ... क्या PostgreSQL के लिए समकक्ष है, या इसे पूरा करने का एक और तरीका है?

+0

नहीं एक जवाब है, लेकिन http://www.postgresonline.com/journal/index.php देख लिया? /archives/14-CrossTab-Queries-in-PostgreSQL-using-tablefunc-contrib.html। – Kuberchaun

+1

http://stackoverflow.com/questions/1943433/postgresql-concat-ws-like- कार्यक्षमता –

+0

एसक्यूलेटिंग समूह \ _concat SQL सर्वर में MySQL फ़ंक्शन सिम्युलेटिंग?] (Http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server) – ntalbs

उत्तर

155

यह शायद एक अच्छा प्रारंभिक बिंदु (संस्करण 8.4+ केवल) है:

SELECT id_field, array_agg(value_field1), array_agg(value_field2) 
FROM data_table 
GROUP BY id_field 

array_agg एक सरणी देता है, लेकिन आप उस पाठ और संपादित करने के रूप में की जरूरत कास्ट कर सकते हैं (नीचे स्पष्टीकरण देखें)। खुद के उपयोग करने से पहले

संस्करण 8.4 करने से पहले, आपको इसे निर्धारित करना है:

CREATE AGGREGATE array_agg (anyelement) 
(
    sfunc = array_append, 
    stype = anyarray, 
    initcond = '{}' 
); 

(PostgreSQL दस्तावेज़ से दूसरे शब्दों में बयान)

स्पष्टीकरण:

  • एक कास्टिंग का परिणाम पाठ के लिए सरणी यह ​​है कि परिणामी स्ट्रिंग घुंघराले ब्रेसिज़ के साथ शुरू होती है और समाप्त होती है। यदि वे वांछित नहीं हैं, तो उन ब्रेसिज़ को कुछ विधि से हटा दिया जाना चाहिए।
  • टेक्स्ट को किसी भी प्रकार का कास्टिंग करना सबसे अच्छा सीएसवी आउटपुट को अनुकरण करता है क्योंकि एम्बेडेड कॉमा वाले तत्व मानक सीएसवी शैली में आउटपुट में डबल-कोट किए जाते हैं। न तो array_to_string() या string_agg() ("group_concat" फ़ंक्शन 9.1 में जोड़ा गया) एम्बेडेड कॉमा के साथ उद्धरण तार, जिसके परिणामस्वरूप सूची में तत्वों की गलत संख्या है।
  • नया 9.1 string_agg() फ़ंक्शन आंतरिक परिणामों को टेक्स्ट में पहले नहीं डाला जाता है। इसलिए "string_agg (value_field)" एक त्रुटि उत्पन्न करेगा यदि value_field एक पूर्णांक है। "string_agg (value_field :: text)" की आवश्यकता होगी। Array_agg() विधि को एकत्रीकरण के बाद केवल एक कलाकार की आवश्यकता होती है (प्रति मूल्य एक कलाकार के बजाय)।
+0

और 9 में।से id_field द्वारा data_table ग्रुप (, array_agg (value_field2) ',') (, array_agg (value_field1) ',') चयन id_field, array_to_string, array_to_string : 0 आप listagg() –

+4

सीएसवी प्राप्त करने के लिए क्वेरी होना चाहिए होगा – Nux

+2

आप यहां सभी मामलों में array_to_string का उपयोग नहीं कर सकते हैं। यदि आपके value_field में एक एम्बेडेड कॉमा है, तो परिणामी सीएसवी गलत है। Array_agg() का उपयोग करके और टेक्स्ट को कास्टिंग एम्बेडेड कॉमा के साथ तारों को सही ढंग से उद्धृत करता है। एकमात्र चेतावनी यह है कि इसमें प्रारंभिक और समापन घुंघराले ब्रेसिज़ भी शामिल हैं, इसलिए मेरा कथन "और आवश्यकतानुसार संपादित करें"। मैं उस बिंदु को स्पष्ट करने के लिए संपादित करूंगा। –

30
SELECT array_to_string(array(SELECT a FROM b),', '); 

के रूप में अच्छी तरह से करना होगा।

+4

यह भी 9.0 से पहले काम करता है - इसे 8.4 के साथ परीक्षण किया गया। 5 – chrpes

+0

एक्सेलेंट !!! मेरे लिये कार्य करता है। टेस्ट भी पोस्टग्रेज 8.3.6। टैंक! – vandersondf

+0

क्या यह [इस टिप्पणी] में कुछ ऐसा करना संभव है (http://stackoverflow.com/questions/2560946/postgresql-group-concat-equivalent#comment23843695_8803563), जहां आप किसी निश्चित क्रम में एकत्र होते हैं? आप एक कॉलम द्वारा ग्रुपिंग को कैसे संभालेंगे और किसी अन्य द्वारा ऑर्डर कर सकते हैं (उदाहरण के लिए, एक अनुदैर्ध्य डेटा सेट के भीतर चर को जोड़ना)? –

178

इस Since 9.0 भी आसान है:

SELECT id, 
     string_agg(some_column, ',') 
FROM the_table 
GROUP BY id 
+18

ध्यान दें कि वाक्यविन्यास आपको स्ट्रिंग में मानों का क्रम निर्दिष्ट करने की अनुमति देता है (या सरणी, 'array_agg' का उपयोग करके) उदा। 'string_agg (some_column, ',' some_column द्वारा ऑर्डर) 'या यहां तक ​​कि' string_agg (उपनाम || ',' forename, ';' उपनाम द्वारा आदेश, अग्रनाम)' – IMSoP

+0

@a_horse_with_no_name मैं आपकी कई महान पोस्ट देखता हूं इसलिए जब मैं विभिन्न पोस्टग्रेस समस्याओं पर काम कर रहा हूं। मुझे आपकी प्रोफ़ाइल में आपसे संपर्क करने का कोई तरीका नहीं दिख रहा है। क्या आप एसओ के बाहर परियोजनाओं पर संचार/काम करने के लिए खुले हैं? अगर नहीं, तो टिप्पणी के माध्यम से आपको पिंग करने के लिए माफ़ी। यदि आप एसओ के बाहर संभावित सहयोग/काम के लिए खुले हैं, तो आप मेरी प्रोफ़ाइल से मुझे यहां तक ​​पहुंच सकते हैं: http://stackoverflow.com/users/2565593/steve-midgley - आप यहां अद्भुत काम कर रहे हैं - धन्यवाद ! (और संपादकों के लिए मैं इस टिप्पणी को छोड़ने के लिए मेटा टिप्पणियों पर निर्भर हूं: http://meta.stackexchange.com/a/58715/278168) –

8

इस तरह का प्रयास करें:

select field1, array_to_string(array_agg(field2), ',') 
from table1 
group by field1;