рд▓рдЪреАрд▓реЗ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде SQL рд╕рд░реНрд╡рд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рджрд┐рдирд╛рдВрдХ рдХреЗ рдмреАрдЪ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕
рдпрджрд┐ рдЖрдкрдиреЗ рдЕрдиреНрдп рд▓реЗрдЦреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХреА рд╣реИ рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддрд╛рд▓рд┐рдХрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрджрд┐ рдирд╣реАрдВ рддреЛ рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдпреЗ рдЗрдВрдЧреНрд▓реИрдВрдб рдФрд░ рд╡реЗрд▓реНрд╕ рдореЗрдВ рдорд╛рдирдХ рдЫреБрдЯреНрдЯрд┐рдпреЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИрдВред рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рдЕрдиреНрдп рджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рд╣реИрдВред
CREATE TABLE Dates.Calendar(CalendarDate DATETIME2 NOT NULL CONSTRAINT PK_CalendarDate PRIMARY KEY,CalendarCA AS (DATEDIFF(DAY,DATEADD(DAY,1-DATEPART(DAY,CalendarDate),CalendarDate),CalendarDate)/7)+1 PERSISTED,CalendarCD AS (DATEDIFF(DAY,CalendarDate,DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,CalendarDate),CalendarDate))))/7)+1 PERSISTED,WeekDayID AS (DATEPART(weekday,[CalendarDate])),WeekDayName AS (case DATEPART(weekday,[CalendarDate]) when (1) then 'Sunday' when (2) then 'Monday' when (3) then 'Tuesday' when (4) then 'Wednesday' when (5) then 'Thursday' when (6) then 'Friday' when (7) then 'Saturday' end))GODECLARE @D DATETIME2='1850-01-01'WHILE @D<='2099-12-31' BEGININSERT INTO Dates.Calendar(CalendarDate) SELECT @DSET @D=DATEADD(DAY,1,@D)ENDGOCREATE TABLE Dates.CalendarHolidays(CalendarDate DATETIME2 NOT NULL,CalendarFunction INT NOT NULL,HolidayType VARCHAR(100) NULL,CONSTRAINT PK_Holidays_Id PRIMARY KEY(CalendarDate,CalendarFunction))GO/*English & Welsh Holidays*/INSERT INTO Dates.CalendarHolidaysSELECT CalendarDate,0,'New Years Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=1 AND DATEPART(DAY,CalendarDate)=1 UNION --New Years DaySELECT CalendarDate,0,'Good Friday' FROM Dates.Calendar WHERE CalendarDate=DATEADD(DAY,-2,Dates.GetEasterDate(DATEPART(YEAR,CalendarDate))) UNION --Good FridaySELECT CalendarDate,0,'Easter Monday' FROM Dates.Calendar WHERE CalendarDate=DATEADD(DAY,1,Dates.GetEasterDate(DATEPART(YEAR,CalendarDate))) UNION --Easter MondaySELECT CalendarDate,0,'May Holidays' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=5 AND WeekDayID=2 AND (CalendarCA=1 OR CalendarCD=1)UNION --May HolidaysSELECT CalendarDate,0,'August Holidays' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=8 AND WeekDayID=2 AND (CalendarCD=1) UNION --August HolidaysSELECT CalendarDate,0,'Christmas Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=12 AND DATEPART(DAY,CalendarDate)=25 UNION --Christmas DaySELECT CalendarDate,0,'Boxing Day' FROM Dates.Calendar WHERE DATEPART(MONTH,CalendarDate)=12 AND DATEPART(DAY,CalendarDate)=26 --Boxing DayGO рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдбреЗрдЯрд╛ рд╣реИ, рд╣рдо рдПрдХ рдРрд╕рд╛ рдлрдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рд╢реБрд░реВ рд╕реЗ рд▓реЗрдХрд░ рдЕрдВрддрд┐рдо рддрд┐рдерд┐рдпреЛрдВ рддрдХ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдкреНрд▓рдЧ рдЗрди рдкрд░ рдирд┐рд░реНрднрд░ 1 рдЪрд░реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ:
- @DateFrom - рдЕрдкрдиреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ рддрд┐рдерд┐
- @ рдХреИрд▓реЗрдиреНрдбрд░рдлрдВрдХреНрд╢рди - рдЕрд╡рдХрд╛рд╢ рдкреНрд░рдХрд╛рд░ рдлрд╝рдВрдХреНрд╢рди рдЬрд┐рд╕реЗ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ
- @DateTo - рдЖрдк рдЬрд┐рд╕ рддрд┐рдерд┐ рд╕реАрдорд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕рдХрд╛ рдЕрдВрдд
- @ AdjustMode - рддрд╛рд░реАрдЦреЛрдВ рдХреЗ рдмреАрдЪ рдХреЗ рджрд┐рдиреЛрдВ рдХреЛ рдкрд╣рд▓реЗ рджрд┐рди рдХреЗ рд╡рд┐рд╢реЗрд╖ рдпрд╛ 1 рд╕рдорд╛рд╡реЗрд╢реА рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рдХрд▓рд┐рдд рдХрд░реЗрдВред
- @ AdjustWeekend - рдЖрдкрдХреА рдЧрдгрдирд╛ рд╕реЗ рд╕рдкреНрддрд╛рд╣рд╛рдВрдд рдирд┐рдХрд╛рд▓ рджреЗрддрд╛ рд╣реИ
- @ AdjustHolidays - рдЫреБрдЯреНрдЯрд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ рдпрджрд┐ рдЕрд╡рдХрд╛рд╢ рдлрд╝рдВрдХреНрд╢рди рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ
CREATE FUNCTION Dates.GetDaysAdjusted(@DateFrom DATETIME2,@CalendarFunction INT,@DateTo AS DATETIME2,@AdjustMode BIT,@AdjustWeekEnds BIT,@AdjustHolidays BIT) RETURNS INT AS BEGIN/*@AdjustMode 0=Count whole days only,1=Any day counts as 1*/IF @DateFrom>@DateTo BEGINDECLARE @T DATETIME2=@DateTo,@F DATETIME2=@DateFromSELECT @DateFrom=@T,@DateTo=@FENDDECLARE @Count AS INT=0,@DateAs DATETIME2=@DateFromWHILE @Date < @DateTo BEGINIF ((DATEPART(WEEKDAY,@Date)IN (1,7)AND @AdjustWeekEnds=1)OREXISTS (SELECT * FROM Dates.CalendarHolidays WHERE CalendarDate=@Date AND CalendarFunction=@CalendarFunctionAND @AdjustHolidays=1))BEGINSELECT @Count = @Count + 1ENDSELECT @Date=DATEADD(DAY,1,@Date)ENDRETURN (DATEDIFF(DAY,@DateFrom,@DateTo)-(@Count))+@AdjustModeENDGOSELECT Dates.GetDaysAdjusted('2014-01-01',0,'2014-01-31',1,1,1)--22SELECT Dates.GetDaysAdjusted('2014-02-01',0,'2014-02-28',1,1,1)--20SELECT Dates.GetDaysAdjusted('2014-05-01',0,'2014-05-02',1,1,1)--2SELECT Dates.GetDaysAdjusted('2014-05-01',0,'2014-05-05',1,1,1)--2SELECT Dates.GetDaysAdjusted('2014-05-01',0,'2014-05-06',1,1,1)--3