[英]Tricky view for Oracle
我有一個表“價格”列:
year, janprc, janqty, febprc, febqty ...
(一年中所有月份的價格和數量)
我需要的是創建一個視圖“monthlyprices”與列:
year, month, price, quantity
使用上表中的數據。 我怎么能這樣做?
謝謝!
以下是如何使用一個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
;
這幾乎是一樣簡單寫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個UNION一次構建一個月的表,
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實例進行測試。
工會的做法對我來說有點痛苦。 您可以這樣做,替換您的真實表名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';
如果UNPIVOT
可用,你一定要使用它。 對於早期版本的Oracle,您可以將表與月份名稱表(生成或預構建)交叉連接,然后使用decode或case語句選擇正確的月份,價格和數量。 這是看起來如何。
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.