SQL不在日期之间(包括NULL)

SQL不在日期之间(包括NULL),sql,tsql,between,Sql,Tsql,Between,我有以下问题。我有一个系统每天每小时运行的检查列表。它知道要运行哪个检查,因为它们在数据库中。现在我制作了一个不同的表,可以为每个应用程序设置维护窗口。我遇到了以下问题 我在应用程序id上加入维护窗口表。如下所示: Select check.appid, check.query, maint.appid from checks as check left join maintenance as maint on maint.appid = check.appid 之后,我想添加一个wher

我有以下问题。我有一个系统每天每小时运行的检查列表。它知道要运行哪个检查,因为它们在数据库中。现在我制作了一个不同的表,可以为每个应用程序设置维护窗口。我遇到了以下问题

我在应用程序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]);
这将返回一个包含当前正在维护的应用程序的列表,因此is不应运行检查

我试着让它成为一个非中间人。但这使我最终没有任何记录,因为当没有维护时,start和enddate将在join上返回null


肮脏的修复可能是强制日期在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]);

这将返回
检查中的所有行
以及
维护中的相应活动信息

当查询运行时,结果将是检查表中的所有行,只有维护表中按appid匹配的行

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

选择check.appid、check.query、maint.appid
从支票到支票
**内部**在maint.appid=check.appid上作为maint加入维护
哪里
SYSDATETIMEOFFSET()
之间
转换(DATETIMEOFFSET,maint.StartDateTime在时区maint.[时区])
及
转换(DATETIMEOFFSET,maint.EndDateTime在时区maint.[TimeZone]);
如果您想要的是所有检查,并且只有维护中属于日期范围的行,那么您可以在where子句中附加一个is NULL

选择check.appid、check.query、maint.appid
从支票到支票
在maint.appid=check.appid上将维护作为maint左连接
哪里
**maint.appid为NULL或**
SYSDATETIMEOFFSET()
之间
转换(DATETIMEOFFSET,maint.StartDateTime在时区maint.[时区])
及
转换(DATETIMEOFFSET,maint.EndDateTime在时区maint.[TimeZone]);

我会尽量说清楚一点;我要所有没有维护和当前时间的检查。所以,当maint中存在一个带有start和enddate的id时,我不想看到它。当我使用上面的查询时,我得到了和以前相同的结果。我要么得到所有的东西。我需要它的另一种方式。所以要明确的是,你想要所有没有任何维护行的检查和那些有维护行的检查,但只有在维护期不包括当前系统日期的情况下才需要?这很有效!当我从中间变为非中间时,我得到了预期的结果!谢谢你。我只是把东西放在了错误的地方。