2014-09-04 23 views
0

我很難在Oracle SQL Developer中使用它。試圖獲得PL/SQL WHILE LOOP與變量一起工作

我想開始一個查詢,然後在它的第一對數行之後運行一個while循環來遍歷數週。我還沒有完成整個查詢,因爲我甚至無法弄清楚如何使用WHILE LOOP這樣的工作。

下面是一個簡單的例子,我知道我需要指定一些日期字段等,但希望你能得到我要去的東西。基本上試圖爲每週交易創建一個新列。默認的Oracle WW或IW值不適用於我們。

我知道這個查詢中有很多其他的調整需要理順,不太清楚逗號應該在哪裏而不是。我不習慣在SQL Developer中工作來完成這些任務。感謝您的任何反饋!

DECLARE 
MyDayVar VARCHAR2(20) := '05-JAN-14'; --sets the start of Week2 
MyWeekVar VARCHAR2(20) := '2'; 
SELECT Customer_Name, 
sum(CASE when PLANNED_SHIP_DATE >= '01-JAN-14' and PLANNED_SHIP_DATE <= '04-JAN-14' then (REVISED_QTY_DUE - QTY_SHIPPED) * SALE_UNIT_PRICE end) as Wk1 --trying to get Week 1 of 2014, 

WHILE 
MyDayVar =< '01-JAN-15' 
LOOP 

sum(CASE when PLANNED_SHIP_DATE >= :MyDayVar and PLANNED_SHIP_DATE <= (:MyDayVar + 7) then (REVISED_QTY_DUE - QTY_SHIPPED) * SALE_UNIT_PRICE end) as Wk + :MyWeekVar --trying to get Week 2 of 2014 and display as 'Wk2', 
MyDayVar = :MyDayVar + 7; --add 7 days to MyDayVar to prepare for the next day; 
MyWeekVar = :MyWeekVar + 1; --add 1 to the Week Variabkle; 
FROM CUSTOM_ORDERS_TABLE 
WHERE PLANNED_SHIP_DATE => '01-JAN-14' --only grab year 2014 data 
END LOOP 
+0

你正在使用s字符串比較來檢查'日期'嗎? 「 – alfasin 2014-09-04 19:20:06

+0

」默認的Oracle WW或IW值不適用於我們。「爲什麼不? – APC 2014-09-05 07:05:17

回答

0

首先,讓我們重新說明你的問題做出明確您的實際目標:要彙總發貨的訂單的價值爲今年每星期。

'你'的定義是七天與星期日盯着。 S,o除非1月1日是星期天,否則你的第一週將是短暫的。推測這個要求是爲什麼你不能使用Oracle IW或WW格式掩碼來生成每週桶。幸運的是,Oracle有其他有用的日期操作可以幫助解決這個問題。

我們可以在具有格式掩碼的日期上使用trunc()以獲得特定值。所以trunc(sysdate, 'yyyy')給了我們今年的第一天。我們可以硬編碼01-JAN-2014,但爲什麼不更靈活?無論如何,find out more。我們可以使用next_day()給我們給定日期的下一個日期。所以next_date(sysdate, 'SUN')給我們下個星期天。請注意,如果今天是星期日,它將給我們日期接下來星期天。 Find out more

我們在日期上使用算術運算。所以sysdate+7給我們下週這一天的日期。

另一個有用的結構是子查詢保理,也就是with子句。爲了提高查詢中出現多次的子查詢的效率,它還提供了生成數據集的方法。 Find out more。在下面的PoC代碼中,我使用Oracle的hierarchical query construct來生成一年中所有星期日的集合。

因此,所有這些工具在我們的指尖就能夠解決您的問題在一個單一的查詢,而無需使用PL/SQL都:

with yr as (select next_day(trunc(sysdate,'yyyy')-1, 'SUN') as first_sunday 
       from dual) 
    , sundays as (select first_sunday + ((level-1)*7) as this_sunday 
         , first_sunday + ((level-2)*7) as prev_sunday 
       from yr 
       connect by level <= 53) 
select sundays.this_sunday as sunday 
     , sum (case when t.planned_ship_date >= sundays.prev_sunday 
         and t.planned_ship_date < sundays.this_sunday 
        then ((t.revised_qty_due - t.qty_shipped) * t.sale_unit_price) 
        else 0 end) as wk_total 
from sundays 
    cross join custom_orders_table t 
where t.planned_ship_date between date '2014-01-01' and date '2014-12-31' 
group by sundays.this_sunday 
order by sundays.this_sunday 

的SQL小提琴有你的問題的一個簡化版本。 Check it out