Рассчитать 8 рабочих дней в прошлом в Informix

Я пытаюсь написать скрипт в оболочке C для выбора данных из базы данных Informix за 8 рабочих дней до этого. Пока у меня есть код sql, который вычисляет 8 дней в прошлом + воскресенье и субботу, это выглядит так:

select *
from ekzo 
where datzah = today-
(case
        when weekday(today) = 1 then 12
        when weekday(today) = 2 then 12
        when weekday(today) = 3 then 12
        when weekday(today) = 4 then 10
        when weekday(today) = 5 then 10
        when weekday(today) = 6 then 10
        when weekday(today) = 0 then 11
        end)

Я создал таблицу "prazkal" с праздниками, которая выглядит так:

datpra  01.01.2014
nazpra  Nova Godina
krapra  SRI

datpra  06.01.2014
nazpra  Bogojavljanje ili Sveta tri kralja
krapra  PON

datpra  20.04.2014
nazpra  Uskrs
krapra  NED

datpra  21.04.2014
nazpra  Uskršnji ponedjeljak
krapra  PON

...

Я не знаю, как расширить свой sql для расчета 8 рабочих дней в прошлом, учитывая выходные и праздничные дни.


person Cikson    schedule 11.07.2014    source источник
comment
общий подход (независимо от dbms) заключается в создании календарной таблицы всех дней, некоторые из которых помечены как рабочие или нерабочие дни (по какой-либо причине). Затем вы подсчитываете (*) количество рабочих дней между двумя датами из этой таблицы. Это отличается от вашего текущего дизайна, который записывает только праздники.   -  person Paul Maxwell    schedule 11.07.2014
comment
См. также Как получить количество рабочих дней в Informix между двумя датами.   -  person Jonathan Leffler    schedule 20.04.2015
comment
Джонатан Леффлер, который может быть новее.   -  person Cikson    schedule 21.04.2015


Ответы (1)


Я бы сделал это в 2 функциях. Первая функция проверяет, является ли день выходным:

create function is_holiday(d datetime year to day)
returning boolean;
    -- define hcnt integer;

    if weekday(d) = 0 or weekday(d) = 6 then
        return 't';
    end if;

    -- code that check if 'd' is marked as holiday in calendar
    --select count(*) into hcnt from prazkal where datpra = d;
    --if hcnt > 0 then
    --  return 't';
    --end if;

    return 'f';
end function;

Вторая функция уменьшает дату на несколько дней, пропуская праздники:

create function move_date_back(start_d datetime year to day, count_days integer)
returning datetime year to day;
define new_d datetime year to day;
define i integer;
    let i = 0;
    let new_d = start_d;

    while i < count_days
        let new_d = new_d - interval(1) day to day;
        if not is_holiday(new_d) then
            let i = i + 1;
        end if;
    end while;

    return new_d;
end function;
person Michał Niklas    schedule 24.07.2014