2009-12-02 75 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 
相关问题