SQL NOT Between dates (including NULL)

SQL NOT Between dates (including NULL)

我遇到了以下问题。我有一份检查系统 运行 的列表,每个 hour/day。它知道哪些检查 运行 因为它们在数据库中。现在我做了一个不同的 table,我可以在其中为每个应用程序设置维护 windows。我正在 运行 解决以下问题。

我加入维护 window table 应用程序 ID。像这样:

Select check.appid, check.query, maint.appid 
from checks as check 
left join maintenance as maint on maint.appid = check.appid

之后,我想添加一个 where 子句,最后得到以下内容

Select check.appid, check.query, maint.appid 
from checks as check 
left join maintenance as maint on maint.appid = check.appid

WHERE
SYSDATETIMEOFFSET()
            BETWEEN 
            CONVERT(DATETIMEOFFSET,maint.StartDateTime AT TIME ZONE maint.[TimeZone]) 
            AND 
            CONVERT(DATETIMEOFFSET,maint.EndDateTime AT TIME ZONE maint.[TimeZone]);

此 return 是一个包含当前正在维护的应用程序的列表,因此不应 运行 进行检查。

我试着让它成为一个 NON BETWEEN。但这让我最终没有任何记录,因为当没有维护时,开始和结束日期将 return 加入时为空。

一个肮脏的修复可能是强制日期为 1990 年或日期为空时的日期,但应该有一个更清晰的选项可用吗?

我认为您想将条件移动到 ON 子句:

select c.appid, c.query, m.appid 
from checks c left join
     maintenance m
     on m.appid = c.appid and
        SYSDATETIMEOFFSET() not between 
            CONVERT(DATETIMEOFFSET, maint.StartDateTime AT TIME ZONE maint.[TimeZone]) AND
            CONVERT(DATETIMEOFFSET,maint.EndDateTime AT TIME ZONE maint.[TimeZone]);

returns checks 中的所有行以及来自 maintenance.

的相应 active 信息

在查询中,结果将是检查 table 中的所有行,并且只有维护 table 中与 appid 匹配的那些行。

如果您只需要那些正在维护的检查,您只需将连接更改为内部连接。还是我理解错了?

Select check.appid, check.query, maint.appid 
from checks as check 
**inner** join maintenance as maint on maint.appid = check.appid

WHERE
SYSDATETIMEOFFSET()
            BETWEEN 
            CONVERT(DATETIMEOFFSET,maint.StartDateTime AT TIME ZONE maint.[TimeZone]) 
            AND 
            CONVERT(DATETIMEOFFSET,maint.EndDateTime AT TIME ZONE maint.[TimeZone]);

如果您想要的是所有检查,并且只有维护中属于日期范围内的那些行,您可以将 IS NULL 附加到 where 子句

Select check.appid, check.query, maint.appid 
from checks as check 
left join maintenance as maint on maint.appid = check.appid

WHERE
**maint.appid IS NULL OR**
SYSDATETIMEOFFSET()
            BETWEEN 
            CONVERT(DATETIMEOFFSET,maint.StartDateTime AT TIME ZONE maint.[TimeZone]) 
            AND 
            CONVERT(DATETIMEOFFSET,maint.EndDateTime AT TIME ZONE maint.[TimeZone]);