SQL Server查询拿到2日期间的工作日数,节假日除外

时间:2019-01-31 18:33:16

标签: sql sql-server date sql-server-2012

我们正在使用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列包含所有假期,例如:12/25 / 2018、12 / 31/2018等。

假日日期 2018年12月25日 2018年12月31日 所以,如果

日期1 = 1/2/19(星期三)

Date2 = 18/27/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 :(得分:0)

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)