मेरे उत्तर को प्रपत्र की तालिका पर आधारित करना:
CREATE TABLE tbl (
sl_no int
, username text
, designation text
, salary int
);
प्रत्येक पंक्ति के परिणामस्वरूप वापस आने के लिए एक नया कॉलम होता है। इस तरह के गतिशील रिटर्न प्रकार के साथ, डेटाबेस में एक कॉल के साथ इसे पूरी तरह से गतिशील बनाना शायद ही संभव है। दो चरणों के साथ समाधान प्रदर्शित करना :
- क्वेरी जेनरेट करें
- उत्पन्न क्वेरी निष्पादित करें
आम तौर पर, यह एक तालिका में रखे जा सकने वाले स्तंभों की अधिकतम संख्या तक सीमित होता है। तो 1600 से अधिक पंक्तियों (या उससे कम) वाली तालिकाओं के लिए कोई विकल्प नहीं है। विवरण:
- एक PostgreSQL चयन क्वेरी में कॉलम की अधिकतम संख्या क्या है
9.3 या पुराने को पोस्ट करें
डायनेमिक सॉल्यूशन के साथ crosstab()
- पूरी तरह से गतिशील, किसी भी तालिका के लिए काम करता है। तालिका का नाम दो . में दें स्थान:
SELECT 'SELECT *
FROM crosstab(
''SELECT unnest(''' || quote_literal(array_agg(attname))
|| '''::text[]) AS col
, row_number() OVER ()
, unnest(ARRAY[' || string_agg(quote_ident(attname)
|| '::text', ',') || ']) AS val
FROM ' || attrelid::regclass || '
ORDER BY generate_series(1,' || count(*) || '), 2''
) t (col text, '
|| (SELECT string_agg('r'|| rn ||' text', ',')
FROM (SELECT row_number() OVER () AS rn FROM tbl) t)
|| ')' AS sql
FROM pg_attribute
WHERE attrelid = 'tbl'::regclass
AND attnum > 0
AND NOT attisdropped
GROUP BY attrelid;
एकल पैरामीटर वाले फ़ंक्शन में लपेटा जा सकता है ...
फ़ॉर्म की क्वेरी जेनरेट करता है:
SELECT *
FROM crosstab(
'SELECT unnest(''{sl_no,username,designation,salary}''::text[]) AS col
, row_number() OVER ()
, unnest(ARRAY[sl_no::text,username::text,designation::text,salary::text]) AS val
FROM tbl
ORDER BY generate_series(1,4), 2'
) t (col text, r1 text,r2 text,r3 text,r4 text)
वांछित परिणाम देता है:
col r1 r2 r3 r4
-----------------------------------
sl_no 1 2 3 4
username A B C D
designation XYZ RTS QWE HGD
salary 10000 50000 20000 34343
unnest()
के साथ सरल समाधान
SELECT 'SELECT unnest(''{sl_no, username, designation, salary}''::text[] AS col)
, ' || string_agg('unnest('
|| quote_literal(ARRAY[sl_no::text, username::text, designation::text, salary::text])
|| '::text[]) AS row' || sl_no, E'\n , ') AS sql
FROM tbl;
- एक से अधिक स्तंभों वाली तालिकाओं के लिए धीमा।
फ़ॉर्म की क्वेरी जेनरेट करता है:
SELECT unnest('{sl_no, username, designation, salary}'::text[]) AS col
, unnest('{10,Joe,Music,1234}'::text[]) AS row1
, unnest('{11,Bob,Movie,2345}'::text[]) AS row2
, unnest('{12,Dave,Theatre,2356}'::text[]) AS row3
, unnest('{4,D,HGD,34343}'::text[]) AS row4
वही परिणाम।
9.4+ पोस्ट करें
डायनेमिक सॉल्यूशन के साथ crosstab()
हो सके तो इसका इस्तेमाल करें। बाकी को मात देता है।
SELECT 'SELECT *
FROM crosstab(
$ct$SELECT u.attnum, t.rn, u.val
FROM (SELECT row_number() OVER () AS rn, * FROM '
|| attrelid::regclass || ') t
, unnest(ARRAY[' || string_agg(quote_ident(attname)
|| '::text', ',') || '])
WITH ORDINALITY u(val, attnum)
ORDER BY 1, 2$ct$
) t (attnum bigint, '
|| (SELECT string_agg('r'|| rn ||' text', ', ')
FROM (SELECT row_number() OVER () AS rn FROM tbl) t)
|| ')' AS sql
FROM pg_attribute
WHERE attrelid = 'tbl'::regclass
AND attnum > 0
AND NOT attisdropped
GROUP BY attrelid;
attnum
. के साथ संचालन वास्तविक कॉलम नामों के बजाय। सरल और तेज। परिणाम में शामिल हों pg_attribute
एक बार फिर या स्तंभ नामों को एकीकृत करें जैसे कि पृष्ठ 9.3 उदाहरण में।
फ़ॉर्म की क्वेरी जेनरेट करता है:
SELECT *
FROM crosstab(
$ct$SELECT u.attnum, t.rn, u.val
FROM (SELECT row_number() OVER () AS rn, * FROM tbl) t
, unnest(ARRAY[sl_no::text,username::text,designation::text,salary::text])
WITH ORDINALITY u(val, attnum)
ORDER BY 1, 2$ct$
) t (attnum bigint, r1 text, r2 text, r3 text, r4 text);
यह उन्नत सुविधाओं की एक पूरी श्रृंखला का उपयोग करता है। समझाने के लिए बहुत कुछ है।
unnest()
के साथ सरल समाधान
एक unnest()
अब समानांतर में अननेस्ट करने के लिए कई सरणियाँ ले सकते हैं।
SELECT 'SELECT * FROM unnest(
''{sl_no, username, designation, salary}''::text[]
, ' || string_agg(quote_literal(ARRAY[sl_no::text, username::text, designation::text, salary::text])
|| '::text[]', E'\n, ')
|| E') \n AS t(col,' || string_agg('row' || sl_no, ',') || ')' AS sql
FROM tbl;
परिणाम:
SELECT * FROM unnest(
'{sl_no, username, designation, salary}'::text[]
,'{10,Joe,Music,1234}'::text[]
,'{11,Bob,Movie,2345}'::text[]
,'{12,Dave,Theatre,2356}'::text[])
AS t(col,row1,row2,row3,row4)
एसक्यूएल फिडल पृष्ठ 9.3 पर चल रहा है।