2011-03-03 113 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()

相關問題