2011-03-03 112 views
6

如何获得结果集中每列的标签,以便在其表中添加名称?将表名添加到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有两个附注设置:full_column_names & short_column_names

+1

我不认为这是可能。 – 2011-03-03 11:26:04

+0

看到SQLAlchemy如何“手动”执行所有这些操作,我也怀疑这可以完成。 – 2011-03-03 12:59:11

+2

这是不可能的一个原因是没有什么可以将结果列魔术般地绑定到表格上。列中的输出可能是由0个或更多列(以及0个或更多个表)组成的表达式。输出的默认列名通常是从列名借用的,但它也可以来自函数名(例如默认情况下'SELECT min(x)'返回名为'min'的列),并且可能是' ?柱?'当没有违约时。我认为,使用'AS'的(不幸的)乏味的建议是唯一的答案,因为它不会对不同行为进行黑客入侵和重新编译Postgres。 – Flimzy 2011-06-15 09:13:05

回答

15

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

做正在寻找的正确方法是创建并使用视图。是的,一次性将所有这些新的列名输出为别名将会有点乏味,但是如果有很多列,这里有一个技巧可以用来利用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] 
+0

非常聪明的解决方案。 – 2012-04-30 06:56:49

+0

这确实很聪明! – 2013-02-26 12:37:14

+0

是否有可能在一个声明中运行此操作?因为现在它需要两次往返。也许使用'EXECUTE'之类的东西,但它只适用于函数。 – davekr 2013-03-15 15:49:11

4

为了得到VIEWDaryl's idea)在一个单个语句使用功能或EXECUTE一个DO command

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注入。例如更多的信息在这里:

,你可能会在Postgres的9.4+使用新to_regclass()

相关问题