#oracle #oracle10g #date-arithmetic
#Oracle #oracle10g #арифметика даты
Вопрос:
Я ищу эквивалент Oracle (10g) для:
DATEADD(weekday, -3, GETDATE())
из T-SQL (SQL Server) . Это вычитает 3 дня недели из текущей даты. Меня не беспокоят праздники или что-то в этом роде (и я могу сам сократить временную часть). Достаточно просто исключить выходные.
Комментарии:
1. Прямым эквивалентом
DATEADD(weekday, -3, GETDATE())
then являетсяselect trunc(sysdate) - 3 from dual
. Я понимаю, что на этот вопрос уже был дан более подробный ответ, но это простое решение, которое я искал!
Ответ №1:
Это может быть выполнено без функции PL / SQL. Просто вычтите разное количество дней в зависимости от дня недели:
select trunc(sysdate) - case to_char(sysdate, 'D')
when '4' then 3 -- thursday minus 3 days
when '5' then 3 -- friday minus 3 days
when '6' then 4 -- saturday minus 4 days
else 5 -- all other days minus 5 days
end
from dual;
Когда вам нужно сделать это, например, 12 дней назад, это будет выглядеть так:
select trunc(sysdate) - case to_char(sysdate, 'D')
when '1' then 18 -- mondays minus 18 days (incl. 3 weekends)
when '2' then 18 -- tuesdays minus 18 days (incl. 3 weekends)
when '6' then 17 -- saturdays minus 17 days (incl. 2 weekends and a saturday)
else 16 -- all others minus 16 days (incl. 2 weekends)
end
from dual;
Пожалуйста, обратите внимание, что день недели зависит от NLS_TERRITORY вашей базы данных (в Америке 1-й день — воскресенье, в большинстве других стран 1-й день — понедельник).
Комментарии:
1. Следует отметить, что это работает только в течение небольшого количества дней (например, 3 в моем примере), где несколько выходных не могут быть фактором.
2. Можете ли вы привести пример? Я думаю, что мое решение может быть легко адаптировано к любому количеству дней.
3. когда число больше 5, вам приходится учитывать несколько выходных дней в зависимости от того, сколько вы набрали.
4. @Кейд Ру, логика не меняется. Я добавил пример к своему ответу.
Ответ №2:
Похоже, вам нужно создать UDF.
CREATE OR REPLACE FUNCTION business_date (start_date DATE,
days2add NUMBER) RETURN DATE IS
Counter NATURAL := 0;
CurDate DATE := start_date;
DayNum POSITIVE;
SkipCntr NATURAL := 0;
Direction INTEGER := 1; -- days after start_date
BusinessDays NUMBER := Days2Add;
BEGIN
IF Days2Add < 0 THEN
Direction := - 1; -- days before start_date
BusinessDays := (-1) * BusinessDays;
END IF;
WHILE Counter < BusinessDays LOOP
CurDate := CurDate Direction;
DayNum := TO_CHAR( CurDate, 'D');
IF DayNum BETWEEN 2 AND 6 THEN
Counter := Counter 1;
ELSE
SkipCntr := SkipCntr 1;
END IF;
END LOOP;
RETURN start_date (Direction * (Counter SkipCntr));
END business_date;
Любезно предоставлено Ларри Бентоном, отсюда.