2012-11-05 11 views
0

下面的查詢行爲有些奇怪:爲什麼左連接返回與NOT IN不同?

SELECT #batches.OutTo, PO_Number, CONVERT(varbinary, #batches.OutTo) , convert  (varbinary, PO_Number), 
    CASE WHEN convert(varbinary, #batches.OutTo) NOT IN (SELECT convert(varbinary, PO_Number) FROM #pos) 
     THEN 'NOT IN' ELSE 'IN' END 
FROM #batches LEFT JOIN #pos ON 
    convert(varbinary, #batches.OutTo) = CONVERT(varbinary, PO_Number) 
WHERE #batches.OutTo IS NOT NULL 
GROUP BY #batches.OutTo, #pos.PO_Number 


OutTo  PO_Number (No column name) (No column name) (No column name) 
311117  NULL  0x333131313137  NULL     IN 
311130  311130  0x333131313330  0x333131313330   IN 
311259  NULL  0x333131323539  NULL     IN 
L001934  L001934  0x4C303031393334 0x4C303031393334  IN 
L001988  NULL  0x4C303031393838 NULL     IN 
L002002  NULL  0x4C303032303032 NULL     IN 

正如你可以看到,左邊的加入能正常運行,但NOT IN不,在返回的值應該是NOT IN。爲什麼是這樣?這是一個錯誤還是SQL我不知道的一個功能?

+3

如果# batch.OutTo是可空的,那麼你應該使用一個LEFT JOIN,或者最好不要存在。由於SQL使用IN與NULL執行相等比較的方式(SQL Server在詢問值<> NULL時必須說「未知」)時,NOT IN是不正確的構造,因此涉及NULL。 –

+0

你是對的 - 我剛回來編輯我的問題,發現你已經回答了。我發現的相關資源(對於任何人在這個問題上磕磕絆絆)是http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql -服務器/ – Hotchips

回答

3

試試這個(你不需要子查詢):

SELECT #batches.OutTo, PO_Number, CONVERT(varbinary(35), #batches.OutTo) , 
    convert  (varbinary(35), PO_Number), 
    CASE WHEN convert(varbinary(35), PO_Number) IS NULL THEN 'NOT IN' 
     ELSE 'IN' END 

FROM #batches 
LEFT JOIN #pos ON 
    convert(varbinary(35), #batches.OutTo) = CONVERT(varbinary(35), PO_Number) 
WHERE #batches.OutTo IS NOT NULL 
GROUP BY #batches.OutTo, #pos.PO_Number 
1

您使用的子查詢SELECT convert(varbinary, PO_Number) FROM #pos沒有任何過濾條件,我相信這會導致附加值並使其返回爲IN,因爲值可能出現在列表中。

要解決這個問題,我想你需要添加合適的地方在子查詢子句,以及如:

SELECT convert(varbinary, PO_Number) FROM #pos 
          WHERE #batches.OutTo IS NOT NULL