2013-06-20 58 views
0

如何在oracle中獲得2013年每個月的最後一個星期四?我需要將這個日期更新到我的表格中。如何在甲骨文2013年的每個月的每個月的最後一個星期四?

我需要一個像

Last Thursday in a year 2013 
---------------------- 
31.01.2013 
28.02.2013 
28.03.2013 
24.04.2013 
30.05.2013 
27.06.2013 
25.07.2013 
29.08.2013 
26.09.2013 
31.10.2013 
28.11.2013 
26.12.2013 

感謝輸出到做要緊。

+1

考慮創建一個[日曆表](http://www.perpendulum.com/2012/06/calendar-table-script-for-oracle/),這樣的查詢變得非常非常容易。 – GarethD

+0

我不是oracle用戶,你沒有提供任何東西供我們測試,但是如果你有一個月結束的列表,你可以把每個星期的一個星期拿出來,找出你需要拿走的東西星期四,然後從月底減去這個數字。 –

+0

@StephLocke OP還能提供什麼,你期待什麼? –

回答

11

這將做到這一點:

select next_day (last_day (add_months(date '2013-01-01', rownum-1))-7, 'THU') as thurs 
from dual 
connect by level <= 12; 

THURS 
--------- 
31-JAN-13 
28-FEB-13 
28-MAR-13 
25-APR-13 
30-MAY-13 
27-JUN-13 
25-JUL-13 
29-AUG-13 
26-SEP-13 
31-OCT-13 
28-NOV-13 
26-DEC-13 

12 rows selected. 

說明:

1)以下select是產生1..12一系列的整數的方式:

select rownum from dual connect by level <= 12; 

2)這將返回2012年12月中的第一個月,從2013年1月1日開始並添加0個月,1個月,...,11個月:

select add_months(date '2013-01-01', rownum-1) 
from dual connect by level <= 12; 

3)last_day函數返回給定日期的月份的最後一天,所以我們現在有2013-01-31,2013-02-28,...,2013-12-31。

4)next_day (date, 'THU')返回指定日期後的下個星期四。爲了得到本月的最後一個星期四,我們採取每月的最後一天,回到7天,然後找到下一個星期四。

+0

'+ 1'嘿,介意解釋邏輯? :) 謝謝。 –

+0

輝煌的解決方案。是否有NLS版本的'next_day'來控制'THU'的語言? –

+0

@Tony Andrews非常感謝.. select to_char(next_day (last_day (add_months(TRUNC(SYSDATE,'YYYY'),rownum-1)) - 7,'THU'),'DD.MM.YYY' ) AS「2013年度上週四」 雙 級別<= 12; – rcmuthu786

3

我會跟dbms_scheduler去:

declare 
    start_dt    date := date '2013-01-01'; 
    months_last_thursday date; 

begin 

    loop 

    dbms_scheduler.evaluate_calendar_string (

     calendar_string => 'FREQ=MONTHLY;BYDAY=-1 THU', 
     start_date  => start_dt, 
     return_date_after => start_dt, 
     next_run_date  => months_last_thursday 

    ); 

    exit when months_last_thursday > date '2013-12-31'; 

    dbms_output.put_line(months_last_thursday); 

    start_dt := months_last_thursday; 

    end loop; 
end; 
/
+1

+1純粹的輝煌 –

0

大廈@劉若英的回答,這可以擴展到一般的(?通用)解決方案:

CREATE OR REPLACE FUNCTION recurring_dates (p_year IN NUMBER, p_rule IN VARCHAR) 
    RETURN dbms_stats.datearray PIPELINED 
AS 
    start_dt DATE; 
    last_dt DATE; 
    next_dt DATE; 
BEGIN 
    start_dt := to_date(to_char(p_year,'fm0000')||'01-01','YYYY-MM-DD'); 
    last_dt := to_date(to_char(p_year,'fm0000')||'12-31','YYYY-MM-DD'); 
    LOOP 
    dbms_scheduler.evaluate_calendar_string(
     calendar_string => p_rule, 
     start_date  => start_dt, 
     return_date_after => start_dt, 
     next_run_date  => next_dt); 
    EXIT WHEN next_dt > last_dt; 
    PIPE ROW (next_dt); 
    start_dt := next_dt; 
    END LOOP; 
END recurring_dates; 
/

你會喂功能在DBMS_SCHEDULER -Syntax中使用日曆字符串,並且它將返回匹配的日期。

@ rcmuthu786的最後一個星期四:

SELECT * FROM TABLE(recurring_dates (2013, 'FREQ=MONTHLY;BYDAY=-1 THU')); 

2013-01-31 
2013-02-28 
2013-03-28 
2013-04-25 
2013-05-30 
... 

或者,每月的第二個星期三:

SELECT * FROM TABLE(recurring_dates (2013, 'FREQ=MONTHLY;BYDAY=2 WED')); 
2013-01-09 
2013-02-13 
2013-03-13 
2013-04-10 
... 

等等,等等......

0

最優雅的方式如下

select thdate from (
select a.*, row_number() over (partition by to_char(thdate,'yyyymm'),day order by thdate desc) row_rank 
from (
select trunc(sysdate,'YEAR') + rownum-1 thdate, 
trim(to_char(trunc(sysdate,'YEAR') + rownum-1,'DAY')) day from dba_objects 
where trunc(sysdate,'YEAR') + rownum-1 < 
trunc(sysdate+365,'YEAR') 
) a where day='THURSDAY' 
) where row_rank=1 

相關問題