整蠱視圖我有一個表「價格」與列:甲骨文
year, janprc, janqty, febprc, febqty ...
(價格和quantyties在一年的所有月份)
我需要的是創建一個視圖「monthlyprices 「與列:
year, month, price, quantity
使用上表中的數據。 我怎麼能這樣做?
謝謝!
整蠱視圖我有一個表「價格」與列:甲骨文
year, janprc, janqty, febprc, febqty ...
(價格和quantyties在一年的所有月份)
我需要的是創建一個視圖「monthlyprices 「與列:
year, month, price, quantity
使用上表中的數據。 我怎麼能這樣做?
謝謝!
這幾乎是一樣簡單寫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
,因爲你知道,不會有任何重複。
使用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
;
這是假設有每年不超過一個記錄。如果每年有多個記錄,請使用UNION ALL保留重複行。
您可能可以使用Oracle 11g的UNPIVOT操作,但我沒有11g的實例開始測試,雖然我害怕。
除非我錯了,'UNPIVOT'只能產生一列(不是兩個),對嗎?他將如何通過'UNPIVOT'獲得價格**和數量**? – 2010-11-12 12:50:31
如果有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;
聯合方法對我來說看起來有點痛苦。你可以這樣做,替換你真實的表名爲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';
我認爲「痛苦」是主觀的。在我自己的(非常主觀的)看來,*這看起來比'聯合'更痛苦。 :) – 2010-11-12 13:00:23
因此'對我'
這不是我會關心的維護,而是性能。我猜想Alex的解決方案比Uber-union更具性能,但我想這取決於數據。 – ninesided 2010-11-12 13:54:07
以下是如何使用一個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
;
+1:絕對groovy! – 2010-11-12 13:03:23
支持@ninesided,鼓舞我與扭曲思維的UNPIVOT語法圖展開激戰。這是值得的努力。 – 2010-11-12 13:07:31
@Janek:語法圖在哪裏?我正在尋找它... – 2010-11-12 13:08:15
首先應用捲起的報紙誰「設計」該表的人... – 2010-11-12 12:16:58
@Tony:只是很高興他們沒有做'2010janprc,2010janqty ... 2011janprc ,2011janqty ...'。 :) – 2010-11-12 12:18:14
有沒有人有11克踢,他們可以看看使用'unpivot'? – ninesided 2010-11-12 12:38:54