Dynamic column in SELECT statement postgres

后端 未结 6 1630
温柔的废话
温柔的废话 2020-12-20 14:55

I am quite new to the postgresql.

what is the best way to achieve this?

SELECT get_columns() 
  FROM table_name;

get_columns(

相关标签:
6条回答
  • 2020-12-20 15:35

    I think your biggest problem is that you need to return rows in a way that PostgreSQL can understand. This means basically, you can return a refcursor or you can return a consistent set of data types. I prefer the latter because it makes the system a bit more consistent from a programming perspective and there are some advanced directions you can take that but I can see the other way too.

    0 讨论(0)
  • 2020-12-20 15:37

    Since you are using COPY FROM to a known large table, CREATE a FUNCTION which returns SETOF bigtable and SELECTs all the columns from the specific type, use NULL AS fieldname for the fields which are not required in that specific case, something like:

    # \d SMALL
         Table "public.small"
     Column |  Type   | Modifiers 
    --------+---------+-----------
     a      | integer | 
     b      | integer | 
     c      | integer | 
     d      | integer | 
    
    # \d LARGE
         Table "public.large"
     Column |  Type   | Modifiers 
    --------+---------+-----------
     a      | integer | 
     b      | integer | 
     c      | integer | 
     d      | integer | 
    
    # CREATE OR REPLACE FUNCTION myData()
     RETURNS SETOF large LANGUAGE SQL AS $$
    SELECT a, 
           CASE WHEN a = 1 
                THEN b 
           ELSE 
                NULL 
    END as b, 
           CASE WHEN a = 2 
                THEN c 
           ELSE 
                NULL
    END AS c, 
    d
    FROM small;
    $$;
    
    # SELECT * FROM mydata();
    # COPY (SELECT * FROM myData()) TO STDOUT;
    

    Obviously SQL might not be the best language to use, so PL/PgSQL or PL/Perl (or whatever) may be appropriate.

    0 讨论(0)
  • 2020-12-20 15:39

    In such case I would use PL/pgSQL function using cursor.

    0 讨论(0)
  • 2020-12-20 15:54

    You wont be able to use a function to generate a column list. And I really don't think this is the best way to approach the problem... That said, you can do it with 8.4 like so:

    CREATE OR REPLACE FUNCTION dyn(p_name VARCHAR)
    RETURNS SETOF RECORD AS
    $$
      DECLARE
        p_sql  TEXT;
      BEGIN
       SELECT 'SELECT ' ||
         CASE p_name WHEN 'foo' THEN ' col1, col2, col3, col4 '
          WHEN 'bar' THEN 'col3, col4, col5, col6'
          WHEN 'baz' THEN 'col1, col3, col4, col6' END ||
       ' FROM mytest'
       INTO p_sql;
       RETURN QUERY EXECUTE p_sql;
      END
    $$ LANGUAGE 'plpgsql';

    Usage would be: SELECT * FROM dyn('foo') AS (one int, two int, three int, four int)

    But honestly I'd suggest just making a view for each device.

    0 讨论(0)
  • 2020-12-20 15:55

    In order to write a dynamic query you would have to do something like:

    EXECUTE 'SELECT '|| get_columns()|| ' FROM table_name' INTO results
    

    Please read the documentation: http://developer.postgresql.org/pgdocs/postgres/plpgsql-statements.html

    0 讨论(0)
  • 2020-12-20 15:56

    This is how you get the columnnames in a table:

    SELECT 
      column_name 
    FROM 
      information_schema.columns 
    WHERE 
      table_name = 'test';
    
    0 讨论(0)
提交回复
热议问题