UNION ALL
आप UNION ALL
. के साथ "काउंटर-पिवट" कर सकते हैं पहला:
SELECT name, array_agg(c) AS c_arr
FROM (
SELECT name, id, 1 AS rnk, col1 AS c FROM tbl
UNION ALL
SELECT name, id, 2, col2 FROM tbl
ORDER BY name, id, rnk
) sub
GROUP BY 1;
आपके द्वारा बाद में अनुरोध किए गए मानों के क्रम को तैयार करने के लिए अनुकूलित। मैनुअल:
बोल्ड जोर मेरा।
LATERAL
सबक्वेरी
VALUES
. के साथ अभिव्यक्ति
LATERAL
आवश्यकता है 9.3 पोस्ट करें या बाद में।
SELECT t.name, array_agg(c) AS c_arr
FROM (SELECT * FROM tbl ORDER BY name, id) t
CROSS JOIN LATERAL (VALUES (t.col1), (t.col2)) v(c)
GROUP BY 1;
वही परिणाम। टेबल के ऊपर से केवल एक ही पास की जरूरत है।
कस्टम समग्र कार्य
या आप इन संबंधित उत्तरों में चर्चा की तरह एक कस्टम समग्र कार्य बना सकते हैं:
- एक में डेटा का चयन करना पोस्टग्रेस सरणी
- क्या PostgreSQL में zip() फ़ंक्शन जैसा कुछ है जो दो सरणियों को जोड़ता है?
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
तब आप कर सकते हैं:
SELECT name, array_agg_mult(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
या, आमतौर पर तेज़, जबकि मानक SQL नहीं:
SELECT name, array_agg_mult(ARRAY[col1, col2]) AS c_arr
FROM (SELECT * FROM tbl ORDER BY name, id) t
GROUP BY 1;
जोड़ा गया ORDER BY id
(जिसे ऐसे समग्र कार्यों में जोड़ा जा सकता है) आपके वांछित परिणाम की गारंटी देता है:
a | {1,2,3,4}
b | {5,6,7,8}
या इस विकल्प में आपकी रुचि हो सकती है:
SELECT name, array_agg_mult(ARRAY[ARRAY[col1, col2]] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
जो दो-आयामी सरणियाँ उत्पन्न करता है:
a | {{1,2},{3,4}}
b | {{5,6},{7,8}}
पिछले वाले को बिल्ट-इन array_agg()
से बदला जा सकता है (और होना चाहिए, जैसा कि यह तेज़ है!) पोस्टग्रेज 9.5 . में या बाद में - सरणियों को एकत्रित करने की अपनी अतिरिक्त क्षमता के साथ:
SELECT name, array_agg(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
वही परिणाम। मैनुअल:
तो बिल्कुल हमारे कस्टम एग्रीगेट फ़ंक्शन array_agg_mult()
. के समान नहीं है;