简体   繁体   中英

Nth Business Day of next year

I have one table name as Table_A, which contain Business Day column and Date column.

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

What I want is, next year date with of same date month according to their corresponding BD

Desired Output:

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

Right now I have written a code, which convert "Date" to next year date then check if it is Saturday then add 2 days, if it is Sunday then add 1 day

My till now code:

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

but not able make it for BD specific. Thanks in advance.

If I understand you correctly, you want to find:

  • the 3rd business day in August 2018
  • the 15th business day in August 2018
  • the 7th business day in September 2018
  • etc.

Here's one way to do it:

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)

It uses 2 CTEs to handle the work:

  • Calendar is a recursive CTE that contains every day in 2018
  • BusinessCalendar filters calendar to only leave out Monday to Friday, then number those days within each month

All that left is joining against your Table_A .

(Note that this doesn't take into account any public holidays, just weekdays and weekends)

Does this do what you want?

select bid,
       max(case when year(date) = 2017 then date end) as date_2017,
       max(case when year(date) = 2018 then date end) as date_2018
from table_A
group by bid;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM