我在理解T-SQL(SQL Server 2000/2005)查询中的以下 WHERE 子句时遇到了一些困难:
update #tempTable
SET
Total_Avg=isnull(TerminationReason,'terminated'),
Individual_Subscriptions=null,
Business_Subscriptions=null,
Other_subscriptions=null,
-- snip. 10 more fields set to NULL.
PMIE_BI=null,
Digital_Editions_BI=null
where
(
AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid)
and (AbcTerminationDate!=19000101 or AbcTerminationDate is null)
and (Total_Avg is not NULL or PrevTotalAvg is not NULL)
)
具体来说,第二个条款对我没有意义 - 由 OR 运算符分隔的2个子条款似乎是矛盾的。
AbcTerminationDate 字段在名为成员的表中声明为 INT NULL 。我认为系统中 19000101 的日期意味着 NULL 或默认值或没有值,即成员 NOT 已终止。因此,如果成员被标记为已终止,则查询似乎会删除大量字段/数字,这将是 AbcTerminationDate 为NULL或具有默认值时。
在不知道更多信息的情况下,您对此有何看法?
答案 0 :(得分:3)
看起来确实是矛盾的。也许他们的意思
and !(AbcTerminationDate==19000101 or AbcTerminationDate is null)
?
答案 1 :(得分:1)
如果“或”arg在()分组之外,它将否定:
AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid)
<强> [编辑] 强> 基本上它是说要从第1个子句中获取任何结果,并执行额外的过滤器以确保它不是19000101或者它是null,很可能是fnGetPeriodFinalDate函数的正常值,以便正确评估。
答案 2 :(得分:1)
无论19000101是什么意思,它都与数据库眼中的NULL不同。 NULL为NULL。如果您尝试将任何其他值评估为NULL,则可能会出现问题,因为NULL表示“未知”。例如,1 = NULL吗?也许它确实如此,也许它没有。实际上,你甚至不能说NULL = NULL,因为每个NULL都是未知的,因此可能或可能不等于另一个。显式检查NULL条件是最安全的。
编辑: 正如我在评论中指出的那样,如果要包含NULL,那么查询的第一部分就排除了这一点。如果应该包含NULL,应该如何编写它:
(
(
(
AbcTerminationDate <= dbo.fnGetPeriodFinalDate(@periodid) AND
AbcTerminationDate != 19000101
) OR
AbcTerminationDate is NULL
) AND
(Total_Avg is not NULL or PrevTotalAvg is not NULL)
)