簡體   English   中英

對Oracle的棘手觀點

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM