Postgresql GROUP_CONCAT के बराबर?


248

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

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

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 के लिए एक समान है, या इसे पूरा करने का एक और तरीका है?





1
मुझे लगता है कि सबसे अच्छा जवाब अभी भी एक और सवाल में है: stackoverflow.com/a/47638417/243233
Jus12

जवाबों:


237

यह शायद एक अच्छा प्रारंभिक बिंदु है (केवल संस्करण 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 () विधि को एकत्रीकरण के बाद केवल एक कास्ट की आवश्यकता होती है (बजाय एक मूल्य प्रति कास्ट)।

1
और 9.0 में आपके पास सूची ()
स्कॉट बेली

6
CSV प्राप्त करने के लिए क्वेरी इस प्रकार होनी चाहिए: SELECT id_field, array_to_string (array_agg (value_field1), '), array_to_string (array_agg (value_field2),', ') सेROM_ data_table GROUP BY id_field
Nux

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


256

9.0 के बाद से यह और भी आसान है:

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

32
ध्यान दें कि वाक्यविन्यास आपको स्ट्रिंग में मानों के क्रम को निर्दिष्ट करने की अनुमति देता है (या उपयोग करके array_agg), उदाहरण के लिए string_agg(some_column, ',' ORDER BY some_column)या यहाँ तक किstring_agg(surname || ', ' || forename, '; ' ORDER BY surname, forename)
IMSoP

8
यह भयानक है जो distinctstring_agg के साथ काम करता है, इसलिए कोई भी उपयोग कर सकता हैstring_agg(distinct some_solumn, ',')
arun

3
ध्यान दें कि यदि आप TEXTएक गैर-कड़े मूल्य (यानी। uuid) है, तो आपको स्तंभ मान डालना होगा । इस प्रकार दिखाई देगाstring_agg(some_column::text, ',')
केंडल

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

साथ ही करेंगे।


क्या इस टिप्पणी में कुछ करना संभव है , जहां आप एक निश्चित क्रम में एकत्र होते हैं? आप एक कॉलम के आधार पर समूहीकरण कैसे करेंगे और किसी दूसरे के द्वारा ऑर्डर करेंगे (उदाहरण के लिए, अनुदैर्ध्य डेटा सेट के भीतर चर को समाप्‍त करने के लिए)?
माइकल ए

15

इस तरह की कोशिश करें:

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

2

और सरणी प्रकार पर काम करने के लिए संस्करण :

select
  array_to_string(
    array(select distinct unnest(zip_codes) from table),
    ', '
);

डुप्लिकेट जवाब, @max_spy ने पांच साल पहले भी यही बात कही थी
एमिल विकस्ट्रॉम

@ EmilVikström: आपके पास गलत होने का अधिकार है, लेकिन ध्यान से पढ़ें। यह न केवल अलग है, लेकिन मैंने एक उदाहरण दिया, जो सरणी प्रकार के साथ काम करता है - जैसे zip_codes होना character varying(5)[]। इसके अलावा, मैंने सत्यापित किया है कि मेरे उद्देश्य के लिए - अनावश्यक की आवश्यकता है, अन्यथा आप देखेंगे ERROR: cannot accumulate arrays of different dimensionality
सोलावोमिर लेनार्ट

1

Postgresql में मेरा सक्सेशन

SELECT cpf || ';' || nome || ';' || telefone  
FROM (
      SELECT cpf
            ,nome
            ,STRING_AGG(CONCAT_WS( ';' , DDD_1, TELEFONE_1),';') AS telefone 
      FROM (
            SELECT DISTINCT * 
            FROM temp_bd 
            ORDER BY cpf DESC ) AS y
      GROUP BY 1,2 ) AS x   

1
आप ORDER BYएक आंतरिक प्रश्न में क्यों कर रहे हैं ? वैसे भी आदेश नहीं मिलेगा?
म्युटेलियन

-1

आशा है कि ओरेकल क्वेरी नीचे काम करेगी।

Select First_column,LISTAGG(second_column,',') 
    WITHIN GROUP (ORDER BY second_column) as Sec_column, 
    LISTAGG(third_column,',') 
    WITHIN GROUP (ORDER BY second_column) as thrd_column 
FROM tablename 
GROUP BY first_column

मैंने इसे rextester.com/l/postgresql_online_compiler पर परीक्षण किया और काम नहीं किया: 42883: फ़ंक्शन सूची (पाठ, अज्ञात, पाठ) मौजूद नहीं है
मैनुअल रोमेरो

ऑरेकल में पोस्टग्रेज्स की तुलना में अलग सिंटैक्स और फ़ंक्शन होते हैं।
हरमन जे। रैडके III
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.