相信大家在寫SQL時都會有遇到Null的經歷吧,在一個table插入Null,與Null作比較等等.
1.Null意思為缺失的值(missing value).
2.三值邏輯(three-valued-logic: TRUE,FALSE,UNKNOWN). 在SQL中有三個邏輯謂詞:TURE,FALSE,UNKNOWN.在大多數的程式設計語言中只有TRUE和FALSE,而在SQL中獨有UNKNOWN,之所有存在與Null有關.
比如做如下比較: Null>32;Null=Null;X+Null>Y;Null<>Null.其計算結果均為UNKNOWN.
可能會有些迷惑,于二值邏輯不同(NOT TURE=FALUSE;NOT FALSE=TRUE)的是NOT UNKNOWN=UNKNOWN.
3.UNKNOWN作為FALSE時的處理. 在SQL中查詢過濾時(ON,WHERE,HAVING)會把UNKNOWN作為FALSE處理,這樣就不會把計算值為UNKNOWN的行添加到下一個結果集中.
4.UNKNOWN作為TRUE時的處理. 在CHECK約束中UNKNOWN卻作為TRUE來處理.
比如在一個table中添加約束條件,約束年齡必須大於零:alter table test1 add constraint ck_age check (age>0),在插入資料時仍然可以插入Null值(前提是這列沒有定義NOT Null約束).insert into test1(age) values(Null)
代碼
createtable test
(
Name varchar(10),
age int
)
--add check constraint age>0
altertable test addconstraint ck_age check (age>0)
insertinto test values
('bluesky',null)
select*from test
(
Name varchar(10),
age int
)
--add check constraint age>0
altertable test addconstraint ck_age check (age>0)
insertinto test values
('bluesky',null)
select*from test
可以插入Null值.
5.再談Null與Null的比較,上面已經講過(Null=Null;Null<>Null),即Null與Null的比較均為UNKNOWN. 但是對於UNIOUE約束,集合操作(如UNION,EXCEPT),排序,分組時,Null與Null為認為是等值的.
5.1 如果一列有UNIQUE約束,就不能插入兩個Null值.
--add unique
altertable test addunique (Name asc)
insertinto test values
(NULL,12),
(NULL,13)
altertable test addunique (Name asc)
insertinto test values
(NULL,12),
(NULL,13)
先定義UNIQUE 約束,insert兩個Null時會出現如下的提示,說明Null在unique中被當做等值處理.
5.2 GROUP BY會把Null分到一個組.
代碼
--drop the unique constraint
ALTER TABLE [dbo].[test] DROP CONSTRAINT [UQ__test__737584F63A81B327]
--insert two null values
insert into test values
(Null,12),
(Null,13)
select * from test
select Name,SUM(age)as sumage from test group by Name
可以看到Null被分成了一組:
5.2 ORDER BY會把Null排序在一起.
5.3 在集合操作時會把Null當成等值的來處理.
總之: 識別在不同的情況下:Null操作時被作為UNKNOWN還是作為TRUE,FALSE,有助於更好的寫SQL及DB設計.
全站熱搜
留言列表