Запрос SQL Server для получения количества рабочих дней между двумя датами, исключая праздничные дни - PullRequest
0 голосов
/ 31 января 2019

Мы используем SQL Server.

В нашем утверждении CASE WHEN мне нужно проверить, не превышает ли число дней между двумя датами> 3 рабочих дня (исключая выходные и праздничные дни).

CASE WHEN end_date - start_date > 3  THEN 0  --> this need to exclude 
    weekend and holidays
WHEN CODE = 1 THEN 1
WHEN CODE =2 THEN 2
ELSE 3
END AS MyColumn

Допустим, у меня есть таблица календаря праздников, в которой есть столбец HolidayDates, содержащий все праздники, например: 25.12.2008, 31.12.2008 и т. Д.

HolidayDates 12/25/ 2018 31.12.2008 Итак, если

Дата1 = 1/2/19 (среда)

Дата2 = 27.12.18 (четверг)

Числорабочий день между датами 1 и 2 составляет 3 дня (12/27, 12/28 и 12/31).

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

Как также исключить выходные и праздничные дни в запросе?

Спасибо.

Отредактировано с ответом:

select start_date, end_date,
datediff(day, mt.start_date, mt.end_date) datediff,
(select
 (datediff(wk, mt.start_date, mt.end_date) )
 +(case when datename(dw, mt.start_date) = 'sunday'   then 1 else 0 end)
 +(case when datename(dw, mt.end_date)   = 'saturday' then 1 else 0 end)
 ) weekend,
(select count(*) from HolidayDates hd
where hd.holydayDate between mt.start_date and mt.end_date
 ) as [holydays (not weekends)],
datediff(day, mt.start_date, mt.end_date)
-(select
(datediff(wk, mt.start_date, mt.end_date) )
+(case when datename(dw, mt.start_date) = 'sunday'   then 1 else 0 end)
+(case when datename(dw, mt.end_date)   = 'saturday' then 1 else 0 end)
) * 2
-(select count(*) from HolidayDates hd
 where hd.holydayDate between mt.start_date and mt.end_date
)
as diff
from MyTable mt

1 Ответ

0 голосов
/ 31 января 2019
create table MyTable
(
 start_date date not null,
 end_date date not null,
 code int not null
)
GO

create table HolidayDates
(
   holydayDate date not null,
   holydayDescription varchar(100) not null
)
GO

insert into MyTable
values
 ('2018-12-25','2019-01-01',101)
,('2018-12-01','2019-01-31',102)
,('2018-12-24','2019-01-02',103)
GO

insert into HolidayDates
values
 ('2018-12-25', 'xmas')
,('2019-01-01', 'Reveillon')
GO

В приведенном ниже запросе вы можете увидеть, как рассчитываются столбцы.

[праздничные дни (не выходные)]: получить все праздничные дни из таблицы, которые также не являются выходными(поэтому они не учитываются дважды).

выходные дни: получить выходные дни в периоде.

Остальные столбцы могут быть самоочевидными

Отказ от ответственности , вы можете немного упростить это, это просто пример запроса о том, как использовать

DATEPART

DATEDIFF

DATNAME

select 
  datediff(day, mt.start_date, mt.end_date) as [total days], 
  (
    select 
      count(*) 
    from 
      HolidayDates hd 
    where 
      hd.holydayDate between mt.start_date 
      and mt.end_date 
      and DATEPART(WEEKDAY, hd.holydayDate) between 2 
      and 6
  ) as [holydays (not weekends) ], 
  (
    select 
      (
        datediff(wk, mt.start_date, mt.end_date) * 2
      ) +(
        case when datename(dw, mt.start_date) = 'sunday' then 1 else 0 end
      ) +(
        case when datename(dw, mt.end_date) = 'saturday' then 1 else 0 end
      )
  ) as weekends, 
  case when datediff(day, mt.start_date, mt.end_date) -(
    select 
      (
        datediff(wk, mt.start_date, mt.end_date) * 2
      ) +(
        case when datename(dw, mt.start_date) = 'sunday' then 1 else 0 end
      ) +(
        case when datename(dw, mt.end_date) = 'saturday' then 1 else 0 end
      )
  ) -(
    select 
      count(*) 
    from 
      HolidayDates hd 
    where 
      hd.holydayDate between mt.start_date 
      and mt.end_date 
      and DATEPART(WEEKDAY, hd.holydayDate) between 2 
      and 6
  ) > 3 then 0 --> this need to exclude weekend and holidays
  when mt.code = 1 then 1 when mt.code = 2 then 2 else 3 end as mycolumn 
from 
  MyTable mt

ВОЗВРАТ

total days  holydays (not weekends) weekends    mycolumn
----------- ----------------------- ----------- -----------
7           2                       2           3
61          2                       18          0
9           2                       2           0

(3 row(s) affected)
...