आप इसे crosstab()
. के साथ कर सकते हैं अतिरिक्त मॉड्यूल टेबलफंक से:
SELECT b
, COALESCE(a1, 0) AS "A1"
, COALESCE(a2, 0) AS "A2"
, COALESCE(a3, 0) AS "A3"
, ... -- all the way up to "A30"
FROM crosstab(
'SELECT colb, cola, 1 AS val FROM matrix
ORDER BY 1,2'
, $$SELECT 'A'::text || g FROM generate_series(1,30) g$$
) AS t (b text
, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int
, a7 int, a8 int, a9 int, a10 int, a11 int, a12 int
, a13 int, a14 int, a15 int, a16 int, a17 int, a18 int
, a19 int, a20 int, a21 int, a22 int, a23 int, a24 int
, a25 int, a26 int, a27 int, a28 int, a29 int, a30 int);
अगर NULL
0
. के बजाय काम भी करता है, यह सिर्फ SELECT *
. हो सकता है बाहरी क्वेरी में।
विस्तृत विवरण:
- PostgreSQL क्रॉसस्टैब क्वेरी
यहां विशेष "कठिनाई":कोई वास्तविक "मूल्य" नहीं है। तो 1 AS val
add जोड़ें अंतिम कॉलम के रूप में।
श्रेणियों की अज्ञात संख्या
एक क्वेरी में पूरी तरह से गतिशील क्वेरी (अज्ञात परिणाम प्रकार के साथ) संभव नहीं है। आपको दो चाहिए प्रश्न। पहले उपरोक्त की तरह गतिशील रूप से एक कथन बनाएं, फिर इसे निष्पादित करें। विवरण:
-
एकल SQL कथन का उपयोग करके एकाधिक अधिकतम () मानों का चयन करना
-
PostgreSQL कॉलम को पंक्तियों में बदलें? स्थानांतरित करें?
-
PostgreSQL में क्रॉसस्टैब के लिए गतिशील रूप से कॉलम जेनरेट करें
-
CASE और GROUP BY के साथ पिवट करने का डायनामिक विकल्प
बहुत अधिक श्रेणियां
यदि आप स्तंभों की अधिकतम संख्या (1600) से अधिक हैं, तो एक क्लासिक क्रॉसस्टैब असंभव है, क्योंकि परिणाम अलग-अलग स्तंभों के साथ प्रदर्शित नहीं किया जा सकता है। (साथ ही, मानव आंखें इतने स्तंभों वाली तालिका को शायद ही पढ़ पाएंगी)
सरणी या दस्तावेज़ प्रकार जैसे hstore
या jsonb
पर्याय हैं। यहाँ सरणियों के साथ एक समाधान है:
SELECT colb, array_agg(cola) AS colas
FROM (
SELECT colb, right(colb, -1)::int AS sortb
, CASE WHEN m.cola IS NULL THEN 0 ELSE 1 END AS cola
FROM (SELECT DISTINCT colb FROM matrix) b
CROSS JOIN (SELECT DISTINCT cola FROM matrix) a
LEFT JOIN matrix m USING (colb, cola)
ORDER BY sortb, right(cola, -1)::int
) sub
GROUP BY 1, sortb
ORDER BY sortb;
-
मूल्यों का पूरा ग्रिड बनाएं:
(SELECT DISTINCT colb FROM matrix) b CROSS JOIN (SELECT DISTINCT cola FROM matrix) a
-
LEFT JOIN
मौजूदा संयोजन, नाम के अंकीय भाग द्वारा क्रम और सरणियों में एकत्रित।right(colb, -1)::int
'A3' से प्रमुख कैरेक्टर को ट्रिम करता है और अंकों को पूर्णांक में कास्ट करता है ताकि हमें एक उचित सॉर्ट ऑर्डर मिल सके।
मूल मैट्रिक्स
यदि आप केवल 0
. की तालिका चाहते हैं एक 1
जहां x = y
, यह सस्ता हो सकता है:
SELECT x, array_agg((x = y)::int) AS y_arr
FROM generate_series(1,10) x
, generate_series(1,10) y
GROUP BY 1
ORDER BY 1;
एसक्यूएल फिडल आपके द्वारा टिप्पणियों में प्रदान किए गए पर निर्माण।
ध्यान दें कि sqlfiddle.com में वर्तमान में एक बग है जो सरणी मानों के प्रदर्शन को समाप्त कर देता है। इसलिए मैंने text
में डाला इसके आसपास काम करने के लिए।