【问题标题】:SQL Server query to get the number of business days between 2 dates, excluding holidaysSQL Server 查询以获取 2 个日期之间的工作日数,不包括节假日
【发布时间】:2019-06-25 07:13:01
【问题描述】:

我们正在使用 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,例如:2018 年 12 月 25 日、2018 年 12 月 31 日等。

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

日期 1 = 2019 年 1 月 2 日(星期三)

日期 2 = 2018 年 12 月 27 日(星期四)

Date1 和 Date2 之间的工作日数为 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

【问题讨论】:

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


【解决方案1】:
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)

【讨论】:

  • 谢谢你,让。我使用了您的解决方案并对其进行了一些更新(我用最终解决方案编辑了我的问题)。
猜你喜欢
  • 2019-06-23
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 2012-08-22
  • 2019-10-03
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
相关资源
最近更新 更多