SQL函数检查日期是否在另一个表的2个日期之间

时间:2018-10-11 07:00:54

标签: sql-server tsql stored-functions

我正在使用一个函数,该函数当前计算传入的两个日期之间的SLA,这将检查NULL项并返回0。

我现在需要考虑新表“ NonBusinessDays”中的日期,并将其从SLA总值中扣除。

我该如何检查两个传入值在它们与其他表日期之间的范围内是否包含任何日期,如果确实如此,则需要从SLA总计中扣除该日期。

当前的桌子坐着;

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

所以我的功能是这样的

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

我希望它检查在传递给函数的参数之间是否存在NonBusinessDays表中的任何日期,但是从SLA撤出将需要很多天。

例如,如果在传入的参数之间存在两个BusinessDays日期,则该日期将减少2。因此,SLA计算为10,但是由于存在2个非工作日,因此SLA变为8。

任何指导将不胜感激,如果您需要更多信息,请告诉我,我会进行修改。

1 个答案:

答案 0 :(得分:2)

我们可以大大减少此功能并考虑非工作日:

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

如果@date1@date2null,则datediff将返回null,相减将离开null,最后合并将其变成0

DATEDIFF计数为边界两个datetime之间的日边界(午夜转换)和删除时间部分的相同值一样多。因此,对于date调用,我们不需要它们作为DATEDIFF。我们确实需要这样的方法来匹配开始日期的非工作日,因此我们将CAST保留在那里,并且由于数据类型不匹配以及出于对称性,我们在结束日期也是如此。

我忽略了当@date2小于@date1时会发生什么,无论如何这都是对该函数的无效输入。

正如我在评论中说的那样,我希望这里有一个完整的日历表,我们可以在工作日内执行COUNT(*)操作,但是您现在不知道这样做。 (这时您开始质疑是否需要功能)