PostgreSQL row to columns

2020-02-05 11:49发布

I'm trying to create a dynamic system that allows the users to import lists of data from Excel so I need to have dynamic columns, ex:

custom_columns_table
id   list_id  data_type       column_name  data              ....
1    1        VARCHAR(255)    email        jhon@example.com  ....
2    1        VARCHAR(255)    name         Jhon              ....

list_table
id
1

I need a result like this:

id email             name  ....
1  jhon@example.com  Jhon  ....

I have found some examples using crosstab but I don`t know if it will work in this case.

Does anyone know how can I do this?

1条回答
▲ chillily
2楼-- · 2020-02-05 12:20

First off, the crosstab() family of functions is not installed in standard PostgreSQL. You need to install the extension tablefunc for this. In PostgreSQL 9.1 you would simply:

CREATE EXTENSION tablefunc;

For older versions have a look at this related answer.

Query

The query could look like this:

SELECT *
FROM   crosstab (
        'SELECT l.id
               ,c.column_name
               ,c.data
         FROM   custom_columns_table c
         JOIN   list_table l ON l.id = c.list_id
         ORDER  BY 1',

        'SELECT DISTINCT column_name
         FROM   custom_columns_table
         ORDER  BY 1')
AS tbl (
    id integer
   ,email text
   ,name text
   );

I use the form of crosstab() with two parameters, because that allows for missing attributes. Like, when a person has no email. Then this form will return NULL for the email column. Detailed explanation:

Function

Or create a function so you don't have to supply a column definition list for every call:

CREATE OR REPLACE FUNCTION f_mycross(text, text)
  RETURNS TABLE (
    id integer
   ,email text
   ,name text)
  AS '$libdir/tablefunc','crosstab_hash' LANGUAGE C STABLE STRICT;

Call:

SELECT * FROM f_mycross(
       'SELECT l.id
              ,c.column_name
              ,c.data
        FROM   custom_columns_table c
        JOIN   list_table l ON l.id = c.list_id
        ORDER  BY 1',

       'SELECT DISTINCT column_name
        FROM   custom_columns_table
        ORDER  BY 1')
查看更多
登录 后发表回答