Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Requête SQL Server pour obtenir le nombre de jours ouvrés entre 2 dates, hors jours fériés

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

Dans la requête ci-dessous, vous pouvez voir comment les colonnes sont calculées.

[vacances (pas les week-ends)] : obtenez tous les jours fériés de votre table ne sont pas aussi des week-ends (ils ne sont donc pas comptés deux fois).

week-end : obtenir des week-ends dans la période.

Le reste des colonnes peut être explicite

Avis de non-responsabilité , vous pouvez simplifier un peu, c'est juste un exemple de requête sur la façon d'utiliser

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

RETOURS

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

(3 row(s) affected)