2011-12-09 75 views
1

我做了一個奇怪的錯誤,我不喜歡的東西如下:SQL Server 2008中沒有空

SELECT * 
FROM table1 
WHERE NAME COLLATE LATIN1_General_CI_AS NOT IN (select name FROM table2) 

Namenvarchar(50)nullTable2name列中的值爲null。然後,由於值爲null,它會匹配table2中不存在的名稱。這意味着這將返回0結果。如果我這樣做:

SELECT * 
FROM table1 
WHERE NAME COLLATE LATIN1_General_CI_AS NOT IN (
    select name FROM table2 where name is not null 
) 

我會得到一些結果。

一個表具有校對Danish_Norwegian_CI_AS和另一個latin1。也許COLLATE是問題的根源?

誰能解釋爲什麼出現這種情況?也許有套理論的東西?

回答

1

它無關整理。嘗試set ansi_nulls off,第一個查詢將按照您的預期工作。

原因是,當您嘗試將某些內容與NULL進行比較(例如,a = NULL或<> NULL)時,結果爲UNKNOWN且整個查詢失敗。如果您將ansi_nulls設置爲off,則相同的比較評估爲TRUE或FALSE,並且查詢「有效」。

換句話說:

WHEN a NOT IN (1, 2, null) 

意味着

WHEN a <> 1 AND a <> 2 AND a <> null 

其中最後一部分a <> null取值爲UNKNOWN和查詢不返回任何行。

1

NULL不起作用,因爲某些人在NOT INNOT EXISTS表達式中使用時會出現這種情況。

基本上,如果子集包含NULL因爲NULL是一個具有未知值的狀態,SQL Server無法確定某個子集不在子集中。

我不認爲整理甚至進入它,查詢是不同的。

See a full explanation of NULL in NOT IN here.

1

我想我會解決此問題,通過使用

SELECT * 
    FROM table1 t1 
WHERE NOT EXISTS (SELECT * 
         FROM table2 t2 
        WHERE (t1.NAME COLLATE LATIN1_General_CI_AS = t2.name) 
         OR (t1.NAME IS NULL AND t2.name IS NULL)) 

沒有華麗的理論雖然只是實踐經驗= P