Добавить имя таблицы для каждого столбца в результирующем наборе данных в SQL? (Postgres конкретно)


Как я могу получить метку каждого столбца в результирующем наборе, чтобы добавить имя к его таблице?

Я хочу, чтобы это происходило для запросов к отдельным таблицам, а также для соединений.

Пример:

  SELECT first_name, last_name FROM person;

Я хочу, чтобы результаты были:

 | person.first_name | person.last_name |
 |-------------------|------------------|
 | Wendy             | Melvoin          |
 | Lisa              | Coleman          |
Я мог бы использовать "AS" для определения псевдонима для каждого столбца, но это было бы утомительно. Я хочу, чтобы это произошло автоматически.
  SELECT first_name AS person.first_name, last_name AS person.last_name FROM person;

Причина моего вопроса заключается в том, что я использую драйвер базы данных, который не предоставляет метаданные. информируя меня о столбце базы данных, откуда результирующий набор получил свои данные. Я пытаюсь написать универсальный код для обработки результирующего набора.

Я хотел бы знать, как это сделать в SQL вообще или, по крайней мере, в Postgres конкретно. У SQLite была такая особенность, хотя я вижу, что теперь она необъяснимо устарела. SQLite имеет два параметра pragma: full_column_names & short_column_names .
2 8

2 ответа:

Я знаю, что этот вопрос немного устарел, но, возможно, кто-то споткнется об ответ, и это поможет им.

Правильный способ сделать то, что вы ищете, - это создать и использовать представление. Да, будет немного утомительно однократно вводить все эти новые имена столбцов в качестве псевдонимов, но если их много, вот трюк, который вы можете использовать, чтобы использовать метаданные PostgreSQL для записи текста представления:
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;';

Запуск этого дает:

?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]

Тогда вы можете скопируйте и выполните результаты, и вуаля:

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] 

Чтобы получить VIEW (идея Дэрила ) в a одно утверждение используйте функцию или DO команда с 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$;

При этом немедленно выполняется команда вида:

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;

Было бы меньше хлопот объединять имена юридических столбцов с ' _ ' вместо '.". Но вы должны быть готовы к нестандартным именам, которые требуют двойного цитирования (и защиты от возможной инъекции SQL) в любом случае.

Вы можете по желанию укажите полное имя таблицы (myschema.person). Имя схемы префиксируется в именах столбцов автоматически, если оно находится за пределами текущего search_path.

Для повторного использования вы обернете это в функцию plpgsql и сделаете имя таблицы параметром text. Все преобразования текста в код очищаются здесь, чтобы предотвратить внедрение SQL. Пример с дополнительной информацией здесь:

И вы можете использовать новый to_regclass() в Postgres 9.4+: