2015-10-03 23 views
5

目前,我有以下格式的表m一排輸出:交叉表函數返回時,我希望多行

id scenario period ct 
2  1   1  1 
2  1   2  1 
2  1   3  1 
2  1   4  1 
2  2   1  1 
2  2   2  1 
2  2   3  1 
2  2   4  1 
2  3   1  1 
2  3   2  1 
2  3   3  1 
2  3   4  1 

我想創建下表:

id scenario period 1 2 3 4 
2  1   1  1 
2  1   2   1 
2  1   3     1 
2  1   4      1 
2  2   1  1 
2  2   2   1 
2  2   3     1 
2  2   4      1 
2  3   1  1 
2  3   2   1 
2  3   3     1 
2  3   4      1 

tablefunc擴展已經在我的Postgres數據庫中創建。我目前正在嘗試使用crosstab()函數來完成數據透視。但是,我得到一個表,如下所示:

id scenario period 1 2 3 4 
2  1   1  1 1 1 1 

我試着查詢:

SELECT * FROM crosstab(
     'SELECT id, scenario, period, ct FROM m 
      ORDER BY 1', 
     'SELECT DISTINCT period FROM m 
      ORDER BY 1') 
AS (id, scenario, period, 1, 2, 3, 4); 
+0

您提出的查詢明顯無效。 (列定義列表缺少數據類型)。什麼是您嘗試的實際查詢? –

+0

我的數據集要大得多,但我想要一個更簡單的例子來展示。我認爲更準確的查詢是: SELECT * FROM交叉( \t \t 'SELECT ID,場景,期間,CT的M \t \t \t ORDER BY 1', \t \t「SELECT DISTINCT期的M \t AS(int int,scenario int,period int,「1」int,「2」int,「3」int,「4」int); –

回答

3

此查詢生成所需輸出:

SELECT id, scenario, period, p1, p2, p3, p4 -- all except aux column rn 
FROM crosstab(
    'SELECT row_number() OVER (ORDER BY id, scenario, period)::int AS rn 
     , id, scenario, period, period, ct 
    FROM m 
    ORDER BY 1' 
, 'VALUES (1), (2), (3), (4)' 
    ) AS (rn int, id int, scenario int, period int, p1 int, p2 int, p3 int, p4 int); 

兩個特殊困難:

  1. 對於row_name,您還沒有唯一的唯一列。我使用row_number()來生成代理鍵:rn。我將它從外部SELECT中移除以匹配您所需的結果。
    您試過的方式,id被認爲是row_name,並且所有輸入行都彙總爲單個輸出行。

  2. 要在結果附加列(scenarioperiod),其中必須出現在ROW_NAME後的類別之前。您必須列出period兩次才能獲得原始列 - 看起來好像多餘。

基礎:

與此相關的具體情況下:


通常情況下,你會有這樣的查詢:

SELECT id, scenario, p1, p2, p3, p4 -- all except aux column rn 
FROM crosstab(
    'SELECT rank() OVER (ORDER BY id, scenario)::int AS rn 
     , id, scenario, period, ct 
    FROM m 
    ORDER BY 1' 
, 'VALUES (1), (2), (3), (4)' 
    ) AS (rn int, id int, scenario int, p1 int, p2 int, p3 int, p4 int); 

像這樣的輸出:

id scenario p1 p2 p3 p4 
2 1   1 1 1 1 
2 2   1 1 1 1 
2 3   1 1 1 1 

注意使用rank()代替row_number()到組(id, scenario)相同組合在一起。
如果計數不全是1,結果會更有意義。

+0

嗨Erwin, 感謝您回答我的問題!我有一個關於交叉表功能的後續問題。事實證明,我希望我的交叉表函數通過從另一個表中選擇ID來指定值列(我的交叉表函數的第二個參數是「SELECT id_prod FROM prod;」)。我如何改變我的查詢結束(在AS(rn int,...)之後)正確顯示這個改變的結果? –