Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

Example:

  SELECT first_name, last_name FROM person;

I want the results to be:

 | person.first_name | person.last_name |
 |-------------------|------------------|
 | Wendy             | Melvoin          |
 | Lisa              | Coleman          |

I could use "AS" to define an alias for each column, but that would be tedious. I want this to happen automatically.

  SELECT first_name AS person.first_name, last_name AS person.last_name FROM person;

The reason for my question is that I am using a database driver that does not provide the meta-data informing me the database column from where the result set got its data. I am trying to write generic code to handle the result set.

I would like to know how to do this in SQL generally, or at least in Postgres specifically.

SQLite had such a feature, though I see it is now inexplicably deprecated. SQLite has two pragma settings: full_column_names & short_column_names.

like image 898
Basil Bourque Avatar asked Mar 03 '11 10:03

Basil Bourque


People also ask

What is Information_schema in PostgreSQL?

The information schema is a built-in schema that's common to every PostgreSQL database. You can run SQL queries against tables in the information_schema to fetch schema metadata for a database. For example, the following query fetches the names of all user-defined tables in a database: SELECT.

WHAT IS WITH clause in PostgreSQL?

The WITH clause allows you to specify one or more subqueries that can be referenced by name in the primary query. The subqueries effectively act as temporary tables or views for the duration of the primary query. Each subquery can be a SELECT , TABLE , VALUES , INSERT , UPDATE or DELETE statement.

How do you name columns in PostgreSQL?

The syntax to rename a column in a table in PostgreSQL (using the ALTER TABLE statement) is: ALTER TABLE table_name RENAME COLUMN old_name TO new_name; table_name.

What is the name of a named group of tables in PostgreSQL?

The fundamental notion in Postgres is that of a table, which is a named collection of rows. Each row has the same set of named columns, and each column is of a specific type. Furthermore, each row has a permanent object identifier (OID) that is unique throughout the database cluster.


2 Answers

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] 
like image 162
Daryl Avatar answered Sep 28 '22 10:09

Daryl


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
like image 23
Erwin Brandstetter Avatar answered Sep 28 '22 08:09

Erwin Brandstetter