2009-12-02 42 views
1

我需要創建具有以下結構的表:SQL創建週期爲幾個星期的表 - 在月末有中斷(Oracle)

calendar week;周開始日期;周結束日期

其中包含從2007年開始直到本週的所有星期。

特別的是,當一個月的月底落在一週內時,這一週就會被切成兩片 - 一個記錄的開始日期是一週的開始,結束日期是最後一天和一個包含本週剩餘時間的日期的記錄(開始日期是新月的第一個,結束日期是一週的最後一天)。

例(一週的開始是星期一):
calendar week; week start date; week end date;
...
2009 cW48; 23.11.2009; 29.11.2009
--"normal" week with 7 days, beginning monday and ending sunday
2009 cW49; 30.11.2009; 30.11.2009
--first part of the CW49, which ends at last day of the month
2009 cW49; 01.12.2009; 06.12.2009
--second part of the CW49, which begins at fist day of the new month
2009 cW50; 07.12.2009; 13.12.2009
--"normal" week, without a monthly break
...

如何在Oracle中創建(SQL或PL SQL)這樣的表?

謝謝
問候
納丁

+1

什麼的Oracle版本? – 2009-12-02 23:14:00

+0

版本是Oracle 10g – hihops 2009-12-07 19:35:12

回答

0

這是一個小的PL/SQL塊創建表。 如果需要,更改表名稱。

-- create table weeks(year number, week number, b_date date, e_date date); 

DECLARE 
    i DATE; 
    s DATE; 
    wk NUMBER; 
    yr NUMBER; 

    FUNCTION getweek(l DATE) RETURN NUMBER IS 
    BEGIN 
     -- !! week of year, iso standard, (31. dec can be on the first week of next year) !! 
     RETURN to_char(l, 'IW'); 
    END; 
BEGIN 
    i := to_date('2007-01-01', 'yyyy-mm-dd'); 
    s := i; 

    DELETE weeks; 

    WHILE i <= to_date('2009-12-31', 'yyyy-mm-dd') LOOP 

     IF trunc(s, 'MONTH') <> trunc(i, 'MONTH') OR 
      getweek(s) <> getweek(i) THEN 

      wk := getweek(s); 
      yr := to_char(s, 'YYYY'); 
      INSERT INTO weeks VALUES (yr, wk, s, i - 1); 

      s := i; 
      i := s; 
     END IF; 

     i := i + 1; 
    END LOOP; 

    i := i - 1; 

    wk := getweek(s); 
    yr := to_char(s, 'YYYY'); 
    INSERT INTO weeks VALUES (yr, wk, s, i); 

    COMMIT; 
END; 
0

您可以創建表是這樣的:

create table weeks(cw, start_date, end_date) 
    as 
    select to_char(gen.d,'YYYY "cW"IW') 
     , min(gen.d) 
     , max(gen.d) 
     from (
      select to_date('01.01.2007','DD.MM.YYYY') + level -1 d 
       from dual 
      connect by level <= 1500 -- approx. number of days 
      ) gen 
    group by 
      to_char(gen.d,'YYYY "cW"IW') 
     , to_char(gen.d,'YYYY MM IW') 
    having min(gen.d) <= sysdate 

的一點是在使用IWMM格式掩碼由他們兩人來獲得星期和月份,然後分組結果的數量。

1

你可以創建你的表是這樣的:

SQL> CREATE TABLE weeks AS 
    2 WITH generator AS (
    3  SELECT DATE '2007-01-01' + LEVEL - 1 dt 
    4  FROM dual 
    5  CONNECT BY LEVEL <= SYSDATE - DATE '2007-01-01' + 1 
    6 ) 
    7 SELECT to_char(dt, 'YYYY "cW"IW') "calendar week", 
    8   dt "week start date", 
    9   least(next_day(dt - 1, to_char(DATE '2007-01-07', 'DAY')), 
10    last_day(dt)) "week end date" 
11 FROM generator 
12 WHERE to_char(dt, 'D') = to_char(DATE '2007-01-01', 'D') -- only mondays 
13  OR to_char(dt, 'dd') = 1 --or first day of the month 
14 ; 

Table created 
SQL> SELECT * 
    2 FROM weeks 
    3 WHERE "week start date" BETWEEN DATE '2009-11-15' AND DATE '2009-12-15'; 

calendar week week start date week end date 
------------- --------------- ------------- 
2009 cW47  16/11/2009  22/11/2009 
2009 cW48  23/11/2009  29/11/2009 
2009 cW49  30/11/2009  30/11/2009 
2009 cW49  01/12/2009  06/12/2009