PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL कॉलम को पंक्तियों में बदलें? स्थानान्तरण?

मेरे उत्तर को प्रपत्र की तालिका पर आधारित करना:

CREATE TABLE tbl (
   sl_no int
 , username text
 , designation text
 , salary int
);

प्रत्येक पंक्ति के परिणामस्वरूप वापस आने के लिए एक नया कॉलम होता है। इस तरह के गतिशील रिटर्न प्रकार के साथ, डेटाबेस में एक कॉल के साथ इसे पूरी तरह से गतिशील बनाना शायद ही संभव है। दो चरणों के साथ समाधान प्रदर्शित करना :

  1. क्वेरी जेनरेट करें
  2. उत्पन्न क्वेरी निष्पादित करें

आम तौर पर, यह एक तालिका में रखे जा सकने वाले स्तंभों की अधिकतम संख्या तक सीमित होता है। तो 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 पर चल रहा है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कुप्पी-sqlalchemy के साथ स्वत:वृद्धिशील प्राथमिक कुंजी बनाने में असमर्थ

  2. 50 मील दूर कैक्यूलेट पॉइंट (उत्तर, 45% पूर्वोत्तर, 45% दप)

  3. PostgreSQL में current_date कैसे काम करता है

  4. PostgreSQL में टेबल को अनपिवट कैसे करें

  5. पोस्टग्रेएसक्यूएल का परिचय