Sql server 这个SQLWHERE子句是什么意思?

Sql server 这个SQLWHERE子句是什么意思?,sql-server,tsql,where-clause,Sql Server,Tsql,Where Clause,我很难理解T-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

我很难理解T-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运算符分隔的两个子条款,似乎相互矛盾

在名为Members的表中,abacterminationDate字段声明为INT NULL。我相信系统中19000101的日期意味着空值、默认值或无值,即成员未终止。因此,如果一个成员被标记为terminated,则查询似乎会清空大量字段/数字,这可能是在AbacterMinationDate为NULL或具有默认值时


在不知道更多信息的情况下,您如何理解它?

如果或arg不在分组范围内,它将否定:

AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid) 
[编辑]
基本上,它的意思是从第1个子句中获取任何正确的结果,并执行额外的筛选以确保它不是19000101或它是null,这很可能是fnGetPeriodFinalDate函数要正确计算的异常值。

如果或arg在分组之外,它将否定:

AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid) 
[编辑]
基本上,它的意思是从第1个子句中获取任何正确的结果,并执行额外的筛选以确保它不是19000101或它是null,这很可能是fnGetPeriodFinalDate函数要正确计算的异常值。

看起来确实是矛盾的。也许他们的意思是 和ABCTerMinerationDate==19000101或ABCTerMinerationDate为空

看起来确实是矛盾的。也许他们的意思是 和ABCTerMinerationDate==19000101或ABCTerMinerationDate为空

无论19000101是什么意思,它在数据库中的含义与NULL不同。空就是空。如果您尝试将任何其他值求值为NULL,则可能会出现问题,因为NULL表示未知。例如,1=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)
)

无论19000101的含义是什么,在数据库中它与NULL并不相同。空就是空。如果您尝试将任何其他值求值为NULL,则可能会出现问题,因为NULL表示未知。例如,1=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)
)

同意,而且上面的代码似乎是相当普遍的做法。仅仅因为abacterDeminationDate不等于19000101并不意味着它等于NULL…正如你所说,你必须专门测试它。我不反对你所说的,我从技术角度理解NULL的含义。但这不是我的问题。在系统中,日期值19000101相当于空值。我更感兴趣的是查询的语义值——它们试图实现什么?如果不是虚拟日期,那么就包含它。如果为空,则包含它。同样,如果希望得到正确的结果,无论语义如何,查询在技术上仍然需要正确。这就是那行代码试图做的——如果日期为NULL,请确保返回正确的结果。但是它做得不好,因为如果它为NULL,那么查询的第一部分可能会失败。但是它做得不好,因为如果它为NULL,那么查询的第一部分可能会失败。这也是我的感觉。虽然这种类型的WHERE子句在整个系统的许多地方都使用。如果是不正确的,那么为什么客户没有更早或更频繁地对此进行投诉。也许它只在某些边缘情况下失败……它只会在AbacterDeminationDate为NULL时失败。如果您的应用程序在默认情况下使用19000101填充,则可能不会发生这种情况。事实上,列允许NULL意味着理论上可能发生这种情况,所以我总是为它编写代码,但可能它就是不允许。同意,上面的代码似乎是相当常见的做法。仅仅因为abacterDeminationDate不等于19000101并不意味着它等于NULL…正如你所说,你必须专门测试它。我不反对你所说的,我从技术角度理解NULL的含义。但这不是我的问题。在系统中,日期值19000101相当于空值。我更感兴趣的是查询的语义值——它们试图实现什么?如果不是的话
然后将虚拟日期包括在内。如果为空,则包含它。同样,如果希望得到正确的结果,无论语义如何,查询在技术上仍然需要正确。这就是那行代码试图做的——如果日期为NULL,请确保返回正确的结果。但是它做得不好,因为如果它为NULL,那么查询的第一部分可能会失败。但是它做得不好,因为如果它为NULL,那么查询的第一部分可能会失败。这也是我的感觉。虽然这种类型的WHERE子句在整个系统的许多地方都使用。如果是不正确的,那么为什么客户没有更早或更频繁地对此进行投诉。也许它只在某些边缘情况下失败……它只会在AbacterDeminationDate为NULL时失败。如果您的应用程序在默认情况下使用19000101填充,则可能不会发生这种情况。列允许NULL的事实意味着理论上可能发生这种情况,所以我总是为它编写代码,但可能它就是不允许。这正是我所想的。希望其他人也能捡到这个。。这就是我的想法。但他们设法把它塞满了,但不知何故,由于某种奇怪的逻辑,它仍然有效,只在某些边缘案例中失败。这正是我所想的。希望其他人也能捡到这个。。这就是我的想法。但是他们设法把它塞满了,但不知怎么的,由于一些奇怪的逻辑,它仍然有效,只在某些边缘情况下失效。谢谢。。有道理。我最感兴趣的是第二条和它的意思,但它的结果可能会否定第一条,所以第一条也需要考虑,以提取含义…谢谢。。有道理。我最感兴趣的是第二条和它的意思,但它的结果可能会否定第一条,所以第一条也需要考虑,以提取含义。。。