SQL 查詢中的 NULL 值

SQL 查詢中的 NULL 值

英文原文地址:https://mitchum.blog/null-values-in-sql-queries/



翻譯:高行行


小結:

1. SQL 裡的 NULL 和其他編程語言裡的 NULL 是完全不同的東西

2. 在SQL中將 NULL 當未知來看

今天的帖子是關於SQL中的NULL值的,由我的朋友和數據庫嚮導Kaley提供。如果你想了解有關 SQL,Oracle 數據庫以及使查詢運行更快的更多信息,請訪問他的網站

這是一個使很多萌新開發人員陷入困境的話題-SQL查詢中的NULL值的概念。

每當你向數據庫發出SQL查詢時……你想知道一列中是否包含NULL值……寫查詢將找到結果的正確方法是什麼?

你應該使用這樣的查詢嗎?

<code>SELECT * FROM SOME_TABLE
WHERE SOME_COLUMN = NULL/<code>
SQL 查詢中的 NULL 值

SQL 查詢中的 NULL 值

要麼!你應該使用這樣的查詢嗎?

<code>SELECT * FROM SOME_TABLE
WHERE SOME_COLUMN IS NULL/<code>

…答案是,你應該使用第二個查詢(SOME_COLUMN IS NULL)。

SQL 查詢中的 NULL 值

現在為什麼呢?

我們不在數據庫中進行其他任何比較時都不要使用“ IS ”關鍵字,對嗎?

如果我們想知道一個字段是否等於一個,我們可以使用如下的WHERE子句:

<code>WHERE SOME_COLUMN = 1/<code>

那麼為什麼我們在IS關鍵字上使用 NULL 值呢?為什麼我們需要區別對待 NULL ?

答案是這樣的:在SQL中,NULL表示“未知”的概念 (因此NULL值表示“未知”值)。

1. Null 為未知

在大多數數據庫中,NULL和空字符串(由 "雙撇號" 或 '' 表示)之間存在差異。

但是,並非所有數據庫都這樣:例如,Oracle 數據庫不允許你使用空字符串。任何時候Oracle數據庫看到一個空字符串,它都會自動將空字符串轉換為NULL值。

但是,對於大多數其他數據庫,NULL值與空字符串的處理方式不同:

  • 空字符串被視為沒有值的已知值。
  • 將NULL值視為未知值

這是我問以下問題的區別:“美國總統西奧多·羅斯福的中間名是什麼?”

  • 一個答案可能是:“嗯,我不知道西奧多·羅斯福的中間名是什麼。”(此想法可以由Theodore Roosevelt的記錄的MIDDLE_NAME列中的NULL值表示)
  • 另一個可能的答案可能是“西奧多·羅斯福總統實際上沒有中間名。他的父母從未給他起過中間名,而且我知道西奧多·羅斯福(Theodore Roosevelt)沒有中間名。(你可以通過在MIDDLE_NAME列中輸入一個空字符串或 '' 來表示)

Oracle 數據庫是最顯著的例外,其中這兩個值實際上都將由NULL表示-除 Oracle 以外的大多數數據庫對 NULL 和空字符串的處理方式都非常不同。

只要你記得 NULL 值代表一個未知值,那麼這將有助於你製作SQL查詢,並幫助你解決使用 NULL 值可能遇到的一些棘手情況。

例如,如果你要使用 WHERE 子句這樣的查詢:

<code>SELECT * FROM SOME_TABLE
WHERE 1 = 1/<code>

該查詢將返回行(假設SOME_TABLE不是空表!),因為表達式“ 1 = 1” 可證明是正確的……它可以被證明是正確的。

如果我要說:

<code>SELECT * FROM SOME_TABLE
WHERE 1 = 0/<code>

…然後數據庫將看到此情況,並將“ 1 = 0”評估為false(這意味著該查詢將永遠不會返回任何行)。

但是如果我要說:

<code>SELECT * FROM SOME_TABLE
WHERE 1 = NULL/<code>

數據庫基本上是這樣的:“我不知道這兩個值(1和我們的黑盒NULL值)是否相等”……因此它不返回任何記錄。

2. 三值邏輯

在SQL查詢中有WHERE子句時,它可以具有三種不同結果之一:

  • 可以是真的(它將返回行)
  • 它可以是錯誤的(並且不會返回行)
  • 或者它可以為 NULL 或未知(未知也不會返回值)

你可能會想,“好吧,但是為什麼我要關心 false 和 null 之間的區別,因為數據庫對這兩個值的處理完全相同?”

好吧,讓我告訴你哪裡可能遇到麻煩:讓我們介紹一下 NOT() 條件。

如果你要說:

<code>SELECT * FROM SOME_TABLE
WHERE NOT(1 = 1)/<code>

然後,數據庫首先要求值1 = 1,然後說:“好吧,那顯然是對的。”

但是隨後它將對其應用 NOT() 條件。數據庫即將運行,“好吧,當被註釋時,它變成了假……所以 NOT() 條件導致我們的WHERE子句在這裡是假的。”

因此,上面的查詢不會返回任何記錄。

SQL 查詢中的 NULL 值

但是,如果你要說:

<code>SELECT * FROM SOME_TABLE
WHERE NOT(1 = 0)/<code>

然後,數據庫首先計算表達式1 = 0,並說:“那顯然是錯誤的。”

但是然後它將應用 NOT() 條件,這將給我們相反的結果,因此它變為true

因此此查詢將返回記錄!

SQL 查詢中的 NULL 值

如果我發出以下查詢怎麼辦?

<code>SELECT * FROM SOME_TABLE
WHERE NOT(1 = NULL)/<code>

數據庫首先要評估 1 = NULL。(請記住,它將把NULL當作一個未知值!)

它會說:“我不能說1是否等於 NULL,因為我不知道 NULL(未知)值是什麼。”

因此,它

不會產生真實的結果也不會產生錯誤的結果 –而是會產生NULL(或未知)結果。

NULL 結果將由 NOT() 運算符解釋。

每當你使用 NULL 並將其置於 NOT() 條件時……結果就是另一個NULL!(未知的反面是……嗯……另一個未知)。

SQL 查詢中的 NULL 值

因此,NOT() 運算符對 null 條件不做任何事情。

所以這些查詢中的……

<code>SELECT * FROM SOME_TABLE
WHERE NOT(1 = NULL)/<code>
<code>SELECT * FROM SOME_TABLE
WHERE 1 = NULL/<code>

…將不返回任何記錄…即使它們是相反的!

3. NULL 和 NOT IN

如果我使用WHERE子句發出這樣的查詢:

<code>SELECT * FROM SOME_TABLE
WHERE 1 IN (1, 2, 3, 4, NULL)/<code>

…那麼顯然 WHERE 子句將是正確的,由於1在我們的 IN 列表中,所以該查詢將返回記錄…

SQL 查詢中的 NULL 值

但是如果我要說:

<code>SELECT * FROM SOME_TABLE
WHERE 1 NOT IN (1, 2, 3, 4, NULL)/<code>

那麼顯然這將是錯誤的,並且該查詢將永遠不會返回記錄,因為數字1出現在我們的IN列表中,並且我們說“ NOT IN”…

SQL 查詢中的 NULL 值

現在,如果我要說這樣的話怎麼辦?

<code>SELECT * FROM SOME_TABLE
WHERE 5 NOT IN (1, 2, 3, 4, NULL)/<code>

此 WHERE 子句將永遠不會返回任何記錄,因為它不是真正的可證明(它不能被證明是真的)。數字5沒有明確出現在“ IN”列表中,但是5可能在我們的“黑盒” NULL值內(數據庫不一定知道 NULL 的值是什麼)。

SQL 查詢中的 NULL 值

這將產生 NULL 結果(表示未知結果),並且此 WHERE 子句永遠不會返回任何記錄。

這就是為什麼將 NULL 值等效為未知值很重要的原因-每當你編寫複雜的

SQL查詢時,它都會為你提供幫助。

希望你現在已經準備好處理SQL查詢中的NULL值!

參考文章

神奇的 SQL 之溫柔的陷阱 → 三值邏輯 與 NULL !


分享到:


相關文章: