将表名前置到SQL结果集中的每一列? (Postgres具体)

时间:2011-03-03 10:43:30

标签: sql postgresql dynamic-sql identifier sql-view

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

我希望在单个表和连接上进行查询时发生这种情况。

示例:

  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 个答案:

答案 0 :(得分:19)

我知道这个问题有点陈旧,但也许有人会绊倒答案,这会帮助他们。

正在寻找您正在寻找的东西的正确方法是创建和使用View。是的,将所有这些新列名称作为别名键入一次会有点单调乏味,但是如果这里有很多列,那么您可以使用它来利用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] 

答案 1 :(得分:5)

要在 单一陈述 中获取VIEWDaryl's idea),请使用函数或DO command {{1} }}:

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$;

使用“_”而不是“。”连接合法列名称会更少麻烦。但是你需要为需要双引号(并防止可能的SQL注入)的非标准名称做好准备。

您可以选择提供模式限定的表名(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; )。如果模式名称在当前search_path之外,则会自动以列名称作为前缀。

重复使用时,将其包装到plpgsql函数中,并使表名为myschema.person参数。此处对所有文本到代码的转换进行了清理,以防止SQL注入。这里有更多信息的示例:

你可以在Postgres 9.4 +中使用新的text