明年第N个工作日

时间:2017-07-31 20:47:08

标签: sql sql-server

我有一个表名为Table_A,其中包含Business Day列和Date列。

BD  |   Date
----|--------
3   | Aug-03-2017
15  | Aug-21-2017
7   | Sep-11-2017
20  | Oct-20-2017
14  | Nov-20-2017

我想要的是,明年根据相应的BD日期与相同的日期月份

期望的输出:

BD  |   Date       | Nxt_yr_Date
----|--------------|------------
3   | Aug-03-2017  | Aug-03-2018
15  | Aug-21-2017  | Aug-21-2018
7   | Sep-11-2017  | Sep-11-2018
20  | Oct-20-2017  | Oct-22-2018
14  | Nov-20-2017  | Nov-20-2018
18  | Dec-27-2017  | Dec-26-2018

现在我已经编写了一个代码,用于转换" Date"到明年的日期,然后检查是否是星期六,然后加2天,如果是星期日再添加1天

我的代码:

select
case 
when datepart(dw,dateadd(year,1,(dateadd(day,1,[Date])))) = 1 
    then dateadd(year,1,(dateadd(day,2,[Date])))
when datepart(dw,dateadd(year,1,(dateadd(day,1,[Date])))) = 7 
    then dateadd(year,1,(dateadd(day,3,[Date])))
    else dateadd(year,1,[Date])
end as Nxt_yr_Date
from Table_A

但不能用于BD特定。 提前谢谢。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,你想找到:

  • 2018年8月第3个工作日
  • 2018年8月的第15个工作日
  • 2018年9月第7个工作日

以下是一种方法:

SET DATEFIRST 7

;WITH
    Calendar(Date) AS
    (
        SELECT      CONVERT(date, '2018-01-01')
        UNION ALL
        SELECT      DATEADD(DAY, 1, Date)
        FROM        Calendar
        WHERE       Date < '2018-12-31'
    ),
    BusinessCalendar(Date, BD) AS
    (
        SELECT      Date
                ,   ROW_NUMBER() OVER (PARTITION BY MONTH(Date) ORDER BY Date)
        FROM        Calendar
        WHERE       DATEPART(WEEKDAY, Date) NOT IN (1, 7)
    )

SELECT          A.BD
        ,       A.Date
        ,       CAL.Date                    AS NextYearDate
FROM            #TableA             A
INNER JOIN      BusinessCalendar    CAL     ON MONTH(A.Date) = MONTH(CAL.Date)
                                           AND A.BD          = CAL.BD
OPTION (MAXRECURSION 0)

它使用2个CTE来处理工作:

  • Calendar是一个递归的CTE,包含2018年的每一天
  • BusinessCalendar过滤日历仅在周一至周五遗漏,然后在每个月内对这些日期进行编号

剩下的就是加入Table_A

(请注意,这并未考虑任何公众假期,只是工作日和周末)

答案 1 :(得分:0)

这样做你想要的吗?

ConnectableObservable