2015-05-04 72 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 *类型的组合。 –