14

如何获取结果集中每列的标签以在其表之前添加名称?

我希望这发生在对单个表的查询以及连接上。

例子:

  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 有两个编译指示设置:full_column_namesshort_column_names

4

2 回答 2

21

我知道这个问题有点老了,但也许有人会偶然发现答案,它会帮助他们。

做你正在寻找的正确方法是创建和使用视图。是的,一次性输入所有这些新列名作为别名会有点乏味,但是如果有很多列,您可以使用以下技巧来利用 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] 
于 2012-04-21T18:10:43.273 回答
6

要在单个语句VIEW中获得(达里尔的想法),请使用函数或命令DOEXECUTE

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)。如果 schema-name 在当前search_path.

为了重复使用,您可以将其包装到一个 plpgsql 函数中,并将表名作为text参数。所有文本到代码的转换都在此处进行了清理,以防止 SQL 注入。此处提供更多信息的示例:

您可能会使用to_regclass()Postgres 9.4+ 中的新功能:

于 2014-01-08T20:21:22.383 回答