2017-08-11 46 views
0

我必须生成一个包含所有非营业日和其下一个工作日的表格。计算几年的下一个工作日

鉴于: 表格存储某些城市的周末。

CREATE TABLE WeekHolidays 
(
    CitiesId int 
,Cities_Name varchar(50) 
,HolidayDate int 
) 

另一台举行公众假期:

CREATE TABLE Holidays 
(
    CitiesId int 
    ,Cities_Name varchar(50) 
    ,HolidayDate datetime 
) 

目前,我产生了周末在未来2047周(近40年)+加上公共假日,如:

SELECT Cities_Id 
      ,Cities_Name 
      ,DATEADD(WEEK,sptv.number,DATEADD(DAY,(((HolidayDate - 1) + 7) %7),DATEADD(week, DATEDIFF(day, 0, getdate())/7, 0))) as HolidayDate 
     FROM WeekHolidays 
    CROSS JOIN master..spt_values sptv 
     WHERE sptv.type = 'P' 
    UNION 
    SELECT Cities_Id 
      ,Cities_Name 
      ,HolidayDate 
     FROM Holidays 

但现在我需要为每个日期添加logik的下一个工作日:向前滚动到不在此表中的第一天(对于每个城市)。

Rextester重现: http://rextester.com/OZTT34904

所以结果应该是这样的:

CitiesId Cities_Name HolidayDate  NextBusinessDay 
3   PARIS   14.07.2017  17.07.2017 
3   PARIS   15.07.2017  17.07.2017 
3   PARIS   16.07.2017  17.07.2017 
3   PARIS   22.07.2017  24.07.2017 
3   PARIS   23.07.2017  24.07.2017 
3   PARIS   29.07.2017  31.07.2017 
3   PARIS   30.07.2017  31.07.2017 
3   PARIS   05.08.2017  07.08.2017 
3   PARIS   06.08.2017  07.08.2017 
3   PARIS   12.08.2017  14.08.2017 
3   PARIS   13.08.2017  14.08.2017 
3   PARIS   15.08.2017  16.08.2017 
3   PARIS   18.08.2017  21.08.2017 
3   PARIS   19.08.2017  21.08.2017 
3   PARIS   20.08.2017  21.08.2017 
3   PARIS   26.08.2017  28.08.2017 
3   PARIS   27.08.2017  28.08.2017 

在例如:HolidayDate = 2017年7月14日的下一个BusinessDay将是2017年7月17日,为15.07。 & 16.07。都包含在HolidayDate列中(星期日&星期日是巴黎的假期)。

我希望现在它更容易理解。

任何想法如何轻松快速地解决这个问题?

在此先感谢! 斯特凡

+1

为什么周末和在不同的表公众假期区分。如果是假期,那是假期。如果你真的需要区分,只需添加一个列节点类型或其他东西。至少应该简化你的结构。 – ADyson

+0

[这可能会为您节省大量时间](https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/)它计算平日,节假日等......你可以为自己的假期轻微编辑亚伦的方法 – scsimon

+0

这些表格是由系统给出的。我不太喜欢它,但我必须应付它。其遗留系统 –

回答

0

你可以试试这个:

with getstarts as (
select mydays.* 
    -- transform the dates to have weekends day as 6 and 7 
    ,case when DATEPART(weekday, Holiday) =1 then 7 
     else DATEPART(weekday, Holiday)-1 end as weekdays 
    FROM (
     YOUR_TABLE 
    ) mydays 
) 

SELECT g.*, DATEADD(day,8-g.weekdays,g.Holiday) as c 
FROM getstarts AS g 
where g.weekdays between 6 and 7 
order by holiday 

我转变的日期有被周一的一周的第一天。然后,我通过添加缺少天

要创建包含日期的表计算的日期都一起来看看这款漂亮的内联表值函数 https://stackoverflow.com/a/30133693/8302316