I have a PostgreSQL function (or table) which gives me the following output:
Sl.no    username    Designation    salary   etc..  1        A           XYZ            10000    ...  2        B           RTS            50000    ...  3        C           QWE            20000    ...  4        D           HGD            34343    ...   Now I want the Output as below:
Sl.no            1       2        3       4       ...  Username        A       B        C       D       ...  Designation     XYZ     RTS      QWE     HGD     ...  Salary          10000   50000    20000   34343   ...   How to do this?
Unnest function generates a table structure of an array in PostgreSQL. Unnest array function is beneficial in PostgreSQL for expanding the array into the set of values or converting the array into the structure of the rows. PostgreSQL offers unnest() function.
The crosstab function produces one output row for each consecutive group of input rows with the same row_name value. The output row_name column, plus any “extra” columns, are copied from the first row of the group. The output value columns are filled with the value fields from rows having matching category values.
In PostgreSQL, the ROW_NUMBER() function is used to assign a unique integer to every row that is returned by a query. Syntax: ROW_NUMBER() OVER( [PARTITION BY column_1, column_2, …] [ORDER BY column_3, column_4, …] )
Basing my answer on a table of the form:
CREATE TABLE tbl (   sl_no int , username text , designation text , salary int );  Each row results in a new column to return. With a dynamic return type like this, it's hardly possible to make this completely dynamic with a single call to the database. Demonstrating solutions with two steps:
Generally, this is limited by the maximum number of columns a table can hold. So not an option for tables with more than 1600 rows (or fewer). Details:
crosstab() Use the first one you can. Beats the rest.
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; Operating with attnum instead of actual column names. Simpler and faster. Join the result to pg_attribute once more or integrate column names like in the pg 9.3 example.
 Generates a query of the form:
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);  This uses a whole range of advanced features. Just too much to explain.
unnest() One unnest() can now take multiple arrays to unnest in parallel.
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;  Result:
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);  SQL Fiddle running on pg 9.6
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; Could be wrapped into a function with a single parameter ...
 Generates a query of the form:
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);  Produces the desired result:
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;  Generates a query of the form:
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  Same result.
SELECT    unnest(array['Sl.no', 'username', 'Designation','salary']) AS "Columns",    unnest(array[Sl.no, username, value3Count,salary]) AS "Values" FROM view_name ORDER BY "Columns"   Reference : convertingColumnsToRows
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With