2015-05-04 13 views
6

Ich habe eine Ansicht, die die folgenden resultset produziert:Postgres - Pivot-Tabelle/Kreuztabelle mit mehr als ein Wert Spalte

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

Und ich brauche es in dem verwandeln:

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

Ich weiß, wie Um dies zu tun, wenn ich nur die current_value Spalte verwende, Kreuzestab verwenden. Wie kann ich current_value und future_value verwenden, um neue Spalten im Zielergebnissatz zu erstellen? Wenn ich nur future_value Spalte zu der crosstab(text) Abfrage hinzufügen, beschwert es sich über "ungültige Quelldaten SQL-Anweisung".

Ich benutze PostgreSQL 9.3.6.

+1

Ich kann die Kreuztabellenabfrage erstellen nur eine Spalte, wenn jemand denkt, dass es hilfreich sein kann. –

+1

Es ist immer hilfreich zu posten, was Sie bisher versucht haben. –

Antwort

4

Eine Möglichkeit, einen Verbundtyp zu verwenden wäre:

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

Oder für Ad-hoc-Nutzung (registriert die Art für die Dauer der Sitzung):

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

Dann laufen die Crosstab, wie Sie es und zersetzen den Verbundtyp kennen:

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

Alle Klammern sind erforderlich!

Basics für crosstab():

+0

Ich denke ein ARRAY oder sogar ein POINT macht hier viel mehr Sinn, aber coole Antwort. –

+0

@EvanCarroll: Ja, wenn alle Spalten denselben Datentyp haben oder es in Ordnung ist, in 'text' zu schreiben. Das obige funktioniert für * jede * Kombination von Typen. –