2013-01-07 124 views
3

我在表中有一個狀態列,它有3個值 - 'N/A','Single','Multiple'。某些行的狀態列有NULL值。SQL服務器查詢中的NULL值

我需要拉起狀態不爲空且不是'N/A'的所有行。基本上,我需要所有狀態爲「單個」或「多個」的行。

我一直在閱讀有關NULL實際上相當於'UNKNOWN'。

如果我說

SELECT * 
FROM t_userstatus 
WHERE status <> 'N/A' 

我得到的結果(含「單」或「多」只有所有行)。

我想知道的是,上述WHERE子句是否總是排除具有NULL值的行?是否是預期行爲?

什麼導致這排除空行,​​即使我沒有明確指定它?

在我的查詢中,我是否必須明確說出狀態IS NOT NULL

我比較新的編程,任何幫助表示讚賞。

回答

5

SQL使用three-valued logic:true,false和unknown。與null的任何比較結果都在unknown

因此null <> 'N/A'評估爲unknown。由於unknown不正確,這意味着該行被排除。

6

這是不正常的行爲N/ASingle & Multiple也一樣)是不相關的NULL的字符串。即使NULL被評估爲未知並且可能不會返回,您應該應該明確使用IS NOT NULL

SELECT [column_list] FROM t_userstatus 
WHERE status IS NOT NULL AND status <> 'N/A' 

我還建議你養成指定列列表的習慣。

+1

我同意你明確地使用is not null爲清晰的原因爲下一個人,但是這是服務器的默認配置的正常行爲。我也同意在正常情況下指定列列表的習慣,但是很少有時候*完全適合列表列的完整列表。 – TimothyAWiseman

2

是的,這是正常的行爲。 A NULL值沒有值,因此它不符合WHERE條件。如果您還想包含空值,則還需要指定IS NOT NULL

2

有點不明顯,SQL有三個有價值的邏輯(true/false/unknown)。任何與NULL的直接比較都將導致值unknown,該值在WHERE子句中被視爲非真。你的狀況;

​​

將換句話說,因爲NULL是從來沒有「不等於」任何事情永遠不會匹配空。

使用比較匹配NULL的唯一方法是使用特殊的空操作IS NULLIS NOT NULL

作爲一個側面說明,life is naturally never quite that simple.

+1

與'null'的比較返回'unknown',而不是'false' – Andomar

+1

@Andomar從三值邏輯的角度來看,這是有道理的。對於SQL Server的內部,文檔表明它確實是錯誤的。 http://msdn.microsoft.com/en-us/library/aa259229(v=sql.80).aspx請參閱備註下的第二段。 – TimothyAWiseman

+3

@TimothyAWiseman - 那時文檔是錯誤的。可能沒人會糾正它,因爲它是用於SQL Server 2000的。[該文章的更新版本](http://msdn.microsoft.com/zh-cn/library/ms188048.aspx)。如果它評估爲「false」,那麼NOT(status <>'N/A')'是真的。事實並非如此。同樣,使用NULL <>'N/A''的檢查約束不允許插入任何行。它的確如此。 –

2

正如其他人所說,空一般是沒有可比性。所以,當狀態爲空時,status!='N/A'返回爲false。

但其他人尚未提及的是,它是通過Ansi_nulls設置進行控制的。默認情況下它處於開啓狀態,而空值不具有可比性(正如你在問題中說的那樣,其背後的原理是它們是未知的,所以錯誤的是它們不一定是N/A)。但是你可以使用

SET ANSI_NULLS OFF 

要改變這種行爲,在這種情況下,null將等於null並且不等於別的。有關MSDN here的更多詳細信息。