Prepend table name to each column in a result set in SQL? (Postgres specifically)

前端 未结 2 1437
耶瑟儿~
耶瑟儿~ 2021-01-04 09:17

How can I get the label of each column in a result set to prepend the name if its table?

I want this to happen for queries on single tables as well as joins.

相关标签:
2条回答
  • 2021-01-04 10:03

    I know this question is a bit old, but perhaps someone will stumble over the answer and it will help them out.

    The proper way to do what you're looking for is to create and use a View. Yes, it will be a bit tedious one-time to type out all those new column names as aliases, but if there are a lot of columns here's a trick you can use to leverage the PostgreSQL metadata to write out the text of the view:

    select 'CREATE OR REPLACE VIEW people AS SELECT ' || 
    (select string_agg(column_name || ' AS person_' || column_name, ', ')
    from information_schema.columns
    where table_name = 'person'
    group by table_name) || 
    ' FROM person;';
    

    running this yields:

    ?column?                                                 
    ------------------------------------------------------------------------------------------------------------- 
    CREATE OR REPLACE VIEW people AS SELECT last_name AS person_last_name, first_name AS person_first_name FROM person; 
    
    1 record(s) selected [Fetch MetaData: 0/ms] [Fetch Data: 0/ms]
    [Executed: 4/21/12 2:05:21 PM EDT ] [Execution: 9/ms]
    

    you can then copy and execute the results and voila:

    select * from people;
    
     person_last_name     person_first_name    
     -------------------  -------------------- 
     Melvoin              Wendy                
     Coleman              Lisa                 
    
     2 record(s) selected [Fetch MetaData: 1/ms] [Fetch Data: 0/ms] 
    
    0 讨论(0)
  • 2021-01-04 10:11

    To get the VIEW (Daryl's idea) in a single statement use a function or a DO command with EXECUTE:

    DO
    $do$
    BEGIN
    
    EXECUTE (
       SELECT format(
          'CREATE TEMP VIEW people AS SELECT %s FROM %I'
         , string_agg(format('%I AS %I', attname, attrelid::regclass || '.' || attname), ', ')
         , attrelid::regclass)
       FROM   pg_attribute
       WHERE  attrelid = 'person'::regclass  -- supply source table name once
       AND    attnum > 0
       AND    NOT attisdropped
       GROUP  BY attrelid
       );
    
    END
    $do$;
    

    This immediately executes a command of the form:

    CREATE OR REPLACE VIEW people AS
    SELECT person_id AS "person.person_id"
         , first_name AS "person.first_name"
         , last_name AS "person.last_name"
    FROM   person;
    

    Would be less hassle to concatenate legal column names with '_' instead of '.'. But you need to be prepared for non-standard names that require double-quoting (and defend against possible SQL injection) anyway.

    You can optionally provide a schema-qualified table name (myschema.person). The schema-name is prefixed in column names automatically if it is outside the current search_path.

    For repeated use, you wrap this into a plpgsql function and make the table name a text parameter. All text-to-code conversion is sanitized here to prevent SQL injection. Example with more information here:

    • Table name as a PostgreSQL function parameter

    And you might use the new to_regclass() in Postgres 9.4+:

    • How to check if a table exists in a given schema
    0 讨论(0)
提交回复
热议问题