Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
322 views
Welcome To Ask or Share your Answers For Others

1 Answer

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')

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...