SQL для создания таблицы с неделями в периоде - с перерывами в конце месяца (Oracle) - PullRequest
1 голос
/ 03 декабря 2009

Мне нужно создать таблицу со следующей структурой:

календарная неделя; дата начала недели; дата окончания недели

, который содержит все недели, начиная с 2007 года и до текущей недели.

Особенность заключается в том, что, когда конец месяца попадает в неделю, неделя делится на два фрагмента: одна запись имеет дату начала, которая является началом недели, а дата окончания - последний день месяц и одна запись, содержащая даты остальной части недели (дата начала - первый из нового месяца, дата окончания - последний день недели).

Пример (начало недели - понедельник):
calendar week; week start date; week end date;<br> ...<br> 2009 cW48; 23.11.2009; 29.11.2009<br> --"normal" week with 7 days, beginning monday and ending sunday<br> 2009 cW49; 30.11.2009; 30.11.2009<br> --first part of the CW49, which ends at last day of the month<br> 2009 cW49; 01.12.2009; 06.12.2009<br> --second part of the CW49, which begins at fist day of the new month<br> 2009 cW50; 07.12.2009; 13.12.2009<br> --"normal" week, without a monthly break<br> ...

Как создать такую ​​таблицу в Oracle (SQL или PL SQL)?

Спасибо,
Привет
Надин

Ответы [ 3 ]

2 голосов
/ 04 декабря 2009

вы можете создать свою таблицу следующим образом:

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
0 голосов
/ 03 декабря 2009

Вы можете создать таблицу следующим образом:

    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

Точка используется в маске форматов IW и MM, чтобы получить номер недели и месяца, а затем сгруппировать результаты по обоим.

0 голосов
/ 03 декабря 2009

это небольшой блок 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...