2015-05-04 71 views
6

我有一個產生以下結果集視圖:Postgres的 - 與多個值列數據透視表/交叉

CREATE TABLE foo 
AS 
    SELECT client_id, asset_type, current_value, future_value 
    FROM (VALUES 
    (1, 0, 10 , 20), 
    (1, 1, 5 , 10), 
    (1, 2, 7 , 15), 
    (2, 1, 0 , 2), 
    (2, 2, 150, 300) 
) AS t(client_id, asset_type, current_value, future_value); 

我需要把它改造成這樣:

client_id a0_cur_val a0_fut_val a1_cur_val a1_fut_val ... 
1   10   20   5   10   
2   NULL   NULL  0   2   

我知道如何如果我僅使用current_value列,則使用交叉表執行此操作。如何使用current_valuefuture_value在目標結果集中生成新列?如果我只是將future_value列添加到crosstab(text)查詢中,它會抱怨「無效的源數據SQL語句」。

我使用PostgreSQL 9.3.6。

+1

我如果有人認爲它可以幫助只用一個柱後的交叉表查詢。 –

+1

發佈您迄今爲止/嘗試的內容總是有幫助的。 –

回答

4

一種方法是使用複合類型:

CREATE TYPE i2 AS (a int, b int); 

或者,對於臨時使用(註冊在會話期間類型):

CREATE TEMP TABLE i2 (a int, b int); 

然後運行交叉表,你知道它和分解複合類型:

SELECT client_id 
    , (a0).a AS a0_cur_val, (a0).b AS a0_fut_val 
    , (a1).a AS a1_cur_val, (a1).b AS a1_fut_val 
    , (a2).a AS a2_cur_val, (a2).b AS a2_fut_val 
FROM crosstab(
     'SELECT client_id, asset_type, (current_value, future_value)::i2 
     FROM foo 
     ORDER BY 1,2' 

     ,'SELECT * FROM generate_series(0,2)' 
    ) AS ct (client_id int, a0 i2, a1 i2, a2 i2); 

所有括號必填

基礎知識crosstab()

+0

我認爲ARRAY或甚至POINT使這裏更有意義,但很酷的答案。 –

+0

@EvanCarroll:是的,當所有列碰巧具有相同的數據類型或可以投射到「文本」時。上述作品適用於* any *類型的組合。 –