2010-11-12 183 views
5

整蠱視圖我有一個表「價格」與列:甲骨文

year, janprc, janqty, febprc, febqty ... 

(價格和quantyties在一年的所有月份)

我需要的是創建一個視圖「monthlyprices 「與列:

year, month, price, quantity 

使用上表中的數據。 我怎麼能這樣做?

謝謝!

+9

首先應用捲起的報紙誰「設計」該表的人... – 2010-11-12 12:16:58

+5

@Tony:只是很高興他們沒有做'2010janprc,2010janqty ... 2011janprc ,2011janqty ...'。 :) – 2010-11-12 12:18:14

+2

有沒有人有11克踢,他們可以看看使用'unpivot'? – ninesided 2010-11-12 12:38:54

回答

1

這幾乎是一樣簡單寫12個子查詢和UNION荷蘭國際集團及其結果放在一起:

CREATE VIEW MONTHLYPRICES AS 

SELECT 
    year  AS year, 
    'January' AS month, 
    janprc  AS price, 
    janqty  AS quantity 
FROM 
    PRICES 

UNION ALL 

SELECT 
    year  AS year, 
    'February' AS month, 
    febprc  AS price, 
    febqty  AS quantity 
FROM 
    PRICES 

UNION ALL 

SELECT 
    year  AS year, 
    'March' AS month, 
    marprc  AS price, 
    marqty  AS quantity 
FROM 
    PRICES 

UNION ALL 

    ... and so on ... 

您可以使用UNION ALL,因爲你知道,不會有任何重複。

1

使用11個工會建立你想一個月表的時間,

with t as (
    select 2008 year, 1 janprc, 1 janqty, 1 febprc, 1 febqty from dual 
    union 
    select 2009,  50,  10,  20,  30  from dual 
    union 
    select 2010,  60,  10,  25,  30  from dual 
) 
select year, 'jan' month, janprc price, janqty quantity from t 
union 
select year, 'feb',  febprc,  febqty   from t 
; 

alt text

這是假設有每年不超過一個記錄。如果每年有多個記錄,請使用UNION ALL保留重複行。

1

您可能可以使用Oracle 11g的UNPIVOT操作,但我沒有11g的實例開始測試,雖然我害怕。

+0

除非我錯了,'UNPIVOT'只能產生一列(不是兩個),對嗎?他將如何通過'UNPIVOT'獲得價格**和數量**? – 2010-11-12 12:50:31

0

如果有UNPIVOT可用,您應該明確地使用它。對於早期版本的Oracle,您可以將表格與月份名稱(生成或預建)交叉連接,然後使用解碼或案例語句選擇正確的月份,價格和數量。這是看起來如何。

create table prices (Year Varchar2(4), JanPrc Number(3), JanQty Number(3), 
    FebPrc Number(5,2), FebQty Number(3), MarPrc Number(3), MarQty Number(3)); 
insert into prices values ('2008',1,500,1,600,1,700); 
insert into prices values ('2009',50,100,20,300,30,800); 
insert into prices values ('2010',60,5,70,10,80,15); 

SELECT Year, Month, DECODE(MonthNumber,1,JanPrc,2,FebPrc,MarPrc) Price, 
    DECODE(MonthNumber,1,JanQty,2,FebQty,MarQty) Quantity 
FROM Prices 
    CROSS JOIN (
    SELECT rownum MonthNumber, 
      to_char(to_date(to_char(rownum,'FM00') || '2000','MMYYYY'), 
       'FMMonth') Month 
     FROM dual CONNECT BY rownum <= 3 
) 
ORDER BY Year, MonthNumber; 
1

聯合方法對我來說看起來有點痛苦。你可以這樣做,替換你真實的表名爲so_4164416,並選擇你想要代表月份的方式 - 可能不是全名(我懷疑還有更好的方法來生成月份名稱!):

create or replace view monthlyprices as 
with tmp_month_num as 
    (select rownum as month_num from dual connect by level <= 12) 
select so.year, 
    trim(to_char(to_date('01/' || tmn.month_num || '/2010','DD/MM/YYYY'), 
     'Month')) month, 
    case tmn.month_num 
     when 01 then so.janprc 
     when 02 then so.febprc 
     when 03 then so.marprc 
     when 04 then so.aprprc 
     when 05 then so.mayprc 
     when 06 then so.junprc 
     when 07 then so.julprc 
     when 08 then so.augprc 
     when 09 then so.sepprc 
     when 10 then so.octprc 
     when 11 then so.novprc 
     when 12 then so.decprc end as price, 
    case tmn.month_num 
     when 01 then so.janqty 
     when 02 then so.febqty 
     when 03 then so.marqty 
     when 04 then so.aprqty 
     when 05 then so.mayqty 
     when 06 then so.junqty 
     when 07 then so.julqty 
     when 08 then so.augqty 
     when 09 then so.sepqty 
     when 10 then so.octqty 
     when 11 then so.novqty 
     when 12 then so.decqty end as quantity 
from so_4164416 so, tmp_month_num tmn 
order by so.year, tmn.month_num; 

select * from monthlyprices where year = 2009 and month = 'January'; 
+0

我認爲「痛苦」是主觀的。在我自己的(非常主觀的)看來,*這看起來比'聯合'更痛苦。 :) – 2010-11-12 13:00:23

+0

因此'對我'。一般來說,我認爲工會很難維持,儘管這可能不是問題。當然,也是主觀的。 – 2010-11-12 13:03:17

+0

這不是我會關心的維護,而是性能。我猜想Alex的解決方案比Uber-union更具性能,但我想這取決於數據。 – ninesided 2010-11-12 13:54:07

9

以下是如何使用一個UNPIVOT語句並且不使用UNION。

with t as (
    select 2008 year, 1 janprc, 500 janqty, 1 febprc, 600 febqty from dual 
    union 
    select 2009,  50,  1000,  20,  3000  from dual 
    union 
    select 2010,  60,  1000,  25,  3000  from dual 
) 
SELECT * 
FROM t 
UNPIVOT (
    (price, quantity) FOR month IN 
    (
    (janprc, janqty) AS 'jan', 
    (febprc, febqty) AS 'feb' 
) 
) 
order by 
    year, month 
; 

alt text

+0

+1:絕對groovy! – 2010-11-12 13:03:23

+2

支持@ninesided,鼓舞我與扭曲思維的UNPIVOT語法圖展開激戰。這是值得的努力。 – 2010-11-12 13:07:31

+0

@Janek:語法圖在哪裏?我正在尋找它... – 2010-11-12 13:08:15