SQL函数检查日期是不是在另一个表的2个日期之间
Posted
技术标签:
【中文标题】SQL函数检查日期是不是在另一个表的2个日期之间【英文标题】:SQL Function check if a date is between 2 dates from another tableSQL函数检查日期是否在另一个表的2个日期之间 【发布时间】:2018-10-11 07:00:54 【问题描述】:我正在使用一个函数,该函数当前计算传入的两个日期之间的 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 个非工作日,这将使其变为 8。
任何指导都将不胜感激,如果您需要更多信息,请告诉我,我会修改。
【问题讨论】:
是否可以说服决定对非工作日建模的人改为使用完整的日历表(我的意思是,来一个,20 年的数据仍然少于 10000 行)?然后,您可以针对此表运行COUNT(*)
,针对您的两个日期之间的所有日期,并标记为工作日。
不幸的是,在这种情况下它不能被更改,这个数据库归一个开发人员所有,我只需要与之合作......我知道......不是正常情况,但我必须妥协和使用我有什么选择。我不是要任何人在经过一些指导后专门为我写这个走向:)
很久没有看到 goto 语句了。这还不灭吗? :)
【参考方案1】:
我们可以大大减少这个功能并考虑到非工作日:
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
或@date2
是null
,则datediff
将返回null
,减法将留下null
,最后合并将其变为0
。
DATEDIFF
计数 边界 两个 datetime
s 之间的日期边界(午夜转换)和删除时间部分的相同值一样多。所以我们不需要它们作为date
s 来调用DATEDIFF
。我们确实需要这样来匹配开始日期的非工作日,因此我们将CAST
保留在那里,而且由于数据类型不匹配和对称性,我们对结束日期执行相同操作。
我忽略了当@date2
小于@date1
时会发生什么,这可能是这个函数的无效输入。
正如我在评论中所说,我更喜欢这里有一个完整的日历表,我们可以在工作日内执行 COUNT(*)
操作,但请理解此时您不可以选择。 (此时你开始质疑是否需要一个函数)
【讨论】:
感谢您的详细解释,您是正确的应用程序确定 date2 不能小于 date1 的验证。我将研究提供的答案,并通过几个测试运行它,看看它是如何工作的,这样我下次遇到这样的事情时可以更好地理解它。我更喜欢日历表,因为还有很多其他原因会使用它,所以我将在下次会议上挑战设计 - 我会很快回复。 这样就完美了,谢谢指导和解释。我已经看了一下,我已经将数据库链接到另一个新的分析数据库,我可以在此期间托管一个日历表。在我为这个建模之前,你对这张桌子的布局有什么建议吗?以上是关于SQL函数检查日期是不是在另一个表的2个日期之间的主要内容,如果未能解决你的问题,请参考以下文章