在SQL中,经常会碰到NULL的数据,由于编程语言如C、C++、C#、JAVA等都有NULL,于是会理所当然的将两者等价,实际上两者是不等价的。在C、C++、C#、JAVA等语中,NULL其实是作为值而存在的。比如C#中创建一个对象Object,我们可以赋值为null,而此时有一点很明确就是这个数据是Object类型。但在SQL中,数据为NULL却是未知的类型,或许有人会说了数据库的列在设计的时候,我们是有设定类型的,比如NVARCHAR、VARCHAR、INT等类型,而且勾选了【允许NULL】之后,就可以存入NULL的数据,所以NULL是值。然而实际却非如此的,允许NULL只是标记说这个数据可以为NULL,而NULL实际并不是真正的值,而是NULL标记。
如果有了这样的认识,那么我们对查询数据的时候,就会很容易理解 =NULL和IS NULL的区别。
=NULL这样的SQL语句,等号表示的是对值的判断,所以必须是值才能判断,而NULL是标记,所以根本不可能判断出来。那么【=NULL】计算出来的纠结是什么值呢?是UNKNOWN。是一个不确定的值。因为是不确定的,所以将=NULL作为WHERE条件查询时,是得不到期望的结果的。
我们也可以这么理解,等号的判断是布尔类型的,正常的逻辑是只有true和false,而实际中非true即false的情况是不能覆盖所有可能的,因为还有一种是不确定的。比如前面走来一个人,正常的逻辑是这个人不是男的就是女的,但是在没有辨析确定之前,是男是女是不确定的,换句语说存在第三种状态。而=NULL就像这三种状态。同理使用>NULL、<NULL、<>NULL等的值类型判断都会是这样的情况。所以当我们所=NULL这样的逻辑作SQL的一部分时就会有预想不到的结果。
而使用IS NULL则不然,IS是对一件事是或否的逻辑判断,NULL是标记,所以IS NULL就是判断该数据是否为NULL的标记。也可以说IS NULL是一个整体,就是有来判断是否为NULL数据的。
对于有unknown数据参入的逻辑判断中,就会影响实际的结果。
如果是NOT的逻辑,这个容易理解,就是“不是”。如果有NOT NULL,那逻辑就是不是NULL的数据。
如果是AND的逻辑,则只要有false,那么结果就一定是false。在没有false的时候,只要有unkown就一定是unknown。只有都是true的时候才是true。即优先顺序是false>unkown>true。
如果是OR的逻辑,则只要有true,那么结果就一定是true。如果没有true而有unknown则必定是unknown。即优先顺序是true>unkown>false。
以上内容可参考《SQL进阶教程》