2016-02-27 2 views
-1

В настоящее время я использую DATE_ADD(date,INTERVAL expr type), чтобы установить дату в качестве триггера в базе данных mySQL.SQL: DATE_ADD (date, INTERVAL expr type) skip weekendends

Я хочу знать, можно ли пропустить выходные (субботу, воскресенье) в качестве части триггера.

+0

Чтобы уточнить, вы хотите изменить 'DATE_ADD (некоторый четверг, INTERVAL 3 DAY)', чтобы он был равен следующему вторнику? –

+0

Да, это правильно – Danielphillips

ответ

1

Вам нужно будет создать собственную функцию для этого. Вы можете посмотреть, как это сделать в this answer, например (просто используйте function вместо procedure). Что касается того, как написать такую ​​функцию, рабочий алгоритм here. Код довольно прост: он проходит через дни и пропускает выходные.

CREATE FUNCTION `DAYSADDNOWK`(addDate DATE, numDays INT) RETURNS date 
BEGIN 
    IF (WEEKDAY(addDate)=5) THEN 
     SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY); 
    END IF; 
    IF (WEEKDAY(addDate)=6) THEN 
     SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY); 
    END IF; 
    WHILE numDays>0 DO 
     SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY); 
     IF (WEEKDAY(addDate)=5) THEN 
      SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY); 
     END IF; 
     IF (WEEKDAY(addDate)=6) THEN 
      SET addDate=DATE_ADD(addDate, INTERVAL 1 DAY); 
     END IF; 
     SET numDays=numDays-1; 
    END WHILE; 
    RETURN addDate; 
END 

В настоящее время SELECT DAYSADDNOWK(CURDATE(), 5) дает 2016-03-07, что является правильным.


Конечно только вы не можете использовать его с дней, поэтому никаких произвольных interval, но ваш вопрос упомянутый date тип данных, и я не совсем понимаю, как можно было бы добавить в месяц, не считая рабочих дней.

0

Эта функция просто создает список дат, начинающихся с даты, приведенной в аргументах, и затем определяет, какая дата - это x количество дней (интервал), не считая дней 1 и 7 (которые являются воскресенью и субботой соответственно на SQL Server).

CREATE FUNCTION [dbo].[udf_days_add_no_wknd] 
    (
    @start_date date 
    , @interval int 
    ) 
RETURNS date 
AS 
BEGIN 

declare @answer date 

; with dates as 
    (
     select @start_date as date_val 
     union all 
     select dateadd(d, 1, date_val) as date_val 
     from dates 
     where date_val < dateadd(d, @interval * 10, @start_date) 
    ) 
    , final as 
    (
     select top 1 lead(ld.date_val, @interval, NULL) over (order by ld.date_val asc) as new_date_val 
     from dates as ld 
     where 1=1 
     and datepart(dw, ld.date_val) not in (1,7) --eliminating weekends 
    ) 
select @answer = (select new_date_val from final) 

return @answer 

END 

Это ничего не стоит, что это решение зависит от наличия SQL Server 2012 или более поздней версии, учитывая использование функции lead().

+0

В этом вопросе упоминается mysql, в котором это не работает. –

Смежные вопросы