Reputation: 119
I am using a function which currently calculates the SLA between two dates passed in, this checks for NULL items and returns 0.
I now need to take into account the dates inside a new table 'NonBusinessDays' and take these off the total SLA value.
How would I check if the two passed in values contain any dates between their range from the other tables dates, if they do they need to take off that date from the SLA total.
Currently the table sits like;
CREATE TABLE #NonBusinessDays(
[id] [uniqueidentifier] NOT NULL,
[date] [date] NOT NULL,
[name] [nvarchar](100) NOT NULL,
[type] [nvarchar](50) NOT NULL)
GO
INSERT INTO #NonBusinessDays
([id]
,[date]
,[name]
,[type])
VALUES
('1DF6A335-56F8-4DA7-B9C3-07DBAC9FBA8D'
,'2019-08-26'
,'Summer bank holiday'
,'PublicHoliday')
('0940FDC9-A875-48C5-BED8-0ABFA3AA5AE8',
'2018-05-07',
'Early May bank holiday',
'PublicHoliday')
GO
So my Function is like this;
CREATE FUNCTION dateSLA
(
@date1 DATETIME,
@date2 DATETIME
)
returns INT
AS
BEGIN
declare @days INT
set @days = 0
IF @date1 IS NULL AND @date2 IS NULL
BEGIN
GOTO Final
END
ELSE IF @date1 IS NOT NULL AND @date2 IS NOT NULL
BEGIN
SET @days = DATEDIFF(DAY, CONVERT(DATE, @date1, 103), CONVERT(DATE, @date2, 103))
GOTO Final
END
Final:
return @days
END
GO
I would like it to check if any dates inside the NonBusinessDays Table are present between the parameters passed into the Function then it would take however many days off the SLA.
Example, if two dates from the BusinessDays exist between the passed in the parameters then this would take 2 off. So the SLA calcualted at 10 but this would make it 8 due to 2 non-business days were present.
Any guidance would be appreciated, if you require any more information please let me know and I will amend.
Upvotes: 2
Views: 2610
Reputation: 239724
We can reduce this function considerably and take into account the non working days:
CREATE FUNCTION dateSLA
(
@date1 DATETIME,
@date2 DATETIME
)
returns INT
AS
BEGIN
return COALESCE(
DATEDIFF(day,@date1,@date2) -
(select COUNT(*) from #NonBusinessDays
where date between CAST(@date1 as date) and CAST(@date2 as date)),
0)
END
GO
If either @date1
or @date2
is null
then the datediff
will return null
, the subtraction will leave null
and finally the coalesce turns this into a 0
.
DATEDIFF
counts boundaries There are just as many day boundaries (transitions at midnight) between two datetime
s and the same values with the time portion removed. So we don't need them as date
s for the DATEDIFF
call. We do need such for matching a non-working day on the start date, so we retain the CAST
there, and also because of the data type mismatch and for symmetry we do the same for the end date.
I'm ignoring what happens when @date2
is less than @date1
, which is presumably an invalid input to this function anyway.
As I said in a comment, I'd prefer a full calendar table here where we could just do the COUNT(*)
operation against the working days, but understand it's not an option at this time for you. (At which point you start questioning the need for a function at all)
Upvotes: 2