2010-12-01 77 views
6

我有一個表格(這是查詢的結果)在postgres中有一組行(數據的複雜總和的結果),如下所示:(列名是每天的名稱,和每一列的值是雙精度。)Postgresql主題?交叉?

 太陽週一     週二   星期三   週四   週五
1.24     1.11     4.51     3.21       2.21         1.01

我需要從一個行選擇的數據這樣的結果大致如下:

日     金額
孫    1.24
週一    1.11
週二  4.51
W ED     3.21
週四2.21
週五          1.01

我有困難纔剛剛開始,因爲我確實需要更改列名的值,並轉動的結果。我試着用crosstab做實驗,但我不完全確定這是我需要的。任何意見或建議,可以讓我走向正確的方向將非常感激。

+0

相關的問題是http://stackoverflow.com/questions/1128737/unpivot-and-postgresql – Unreason 2010-12-01 21:03:50

回答

0

我不知道直接實施的,但也許像http://www.mail-archive.com/[email protected]/msg00109.html可以讓你開始

當然,如果你並不需要一個靈活的解決方案,你可以做

SELECT 'Sun' AS Day, Sun AS Value FROM TABLE WHERE ... 
UNION ALL 
SELECT 'Mon' AS Day, Mon AS Value FROM TABLE WHERE ... 
UNION ALL 
SELECT 'Tue' AS Day, Tue AS Value FROM TABLE WHERE ... 
UNION ALL 
SELECT 'Wed' AS Day, Wed AS Value FROM TABLE WHERE ... 
UNION ALL 
SELECT 'Thu' AS Day, Thu AS Value FROM TABLE WHERE ... 
UNION ALL 
SELECT 'Fri' AS Day, Fri AS Value FROM TABLE WHERE ... 

(星期六有空嗎?)

1

測試對象:

create table t (sun numeric, 
       mon numeric, 
       tue numeric, 
       wed numeric, 
       thu numeric, 
       fri numeric); 

insert into t(sun, mon, tue, wed, thu, fri) 
values(1.24, 1.11, 4.51, 3.21, 2.21, 1.01); 

alternat香港專業教育學院改爲@非理性的回答沒有union

select day[i], amount[i] 
from (select generate_series(1,6) as i, 
       array['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'] as day, 
       array[sun, mon, tue, wed, thu, fri] as amount 
     from t) z; 

,如果你需要更通用的,你可以做這樣的事情:

create or replace function unpivot(t) returns setof record 
          language plpgsql immutable strict as $$ 
declare 
    q record; 
    r record; 
begin 
    for q in (select attname, attnum 
      from pg_attribute 
      where attnum>0 and attrelid = (select oid 
              from pg_class 
              where relname = 't')) loop 
    for r in execute 'select '''||q.attname||'''::text, '|| 
          '('||$1::text||'::t).'||q.attname||'::numeric' loop 
     return next r; 
    end loop; 
    end loop; 
    return; 
end;$$; 

select * 
from unpivot((select row(t.*)::t from t)) 
     as foo(day text, amount numeric); 

,你可能會有點整潔的8.4與一個using條款在execute但我不能測試,因爲我在8.3

3

修改@Jack道格拉斯的第一個答案:

SELECT unnest(array['sun', 'mon', 'tue', 'wed', 'thu', 'fri']) AS day, 
     unnest(array[sun, mon, tue, wed, thu, fri]) AS amount 
FROM t; 

根據9,成本稍低一點。0查詢規劃:

Seq Scan on t (cost=0.00..11.62 rows=360 width=192)

Subquery Scan on z (cost=0.00..12.16 rows=360 width=68) -> Seq Scan on t (cost=0.00..11.26 rows=360 width=192)