2013-03-13 54 views
1

我有這個查詢將正確返回IN子句的一部分的值,但是當我將其更改爲NOT IN時,它不會返回任何內容。
有沒有人有任何建議?SQL IN工作但NOT IN不起作用

select distinct 
    CAST(w.work_area AS CHAR(4)) || s.code_id as WATT 
from 
    sys_code s, 
    work_area_master w 
where 
    s.code_type = '590' 
    and (
     CAST(w.work_area AS CHAR(4)) || s.code_id 
    ) 
    in (
     select substr(misc_flags, 1,6) 
     from sys_code where code_type = 'STA' 
    ); 
+2

提示:NULLs會使'IN'行爲與你期望的不同。 – wildplasser 2013-03-13 18:20:15

+5

'NULL'與您的結果混淆,或每行都在該選項中 – Lamak 2013-03-13 18:21:09

+1

'FROM sys_code s,work_area_master w'看起來不相關。 Mybe你想加入他們的一些共同的關鍵字? – wildplasser 2013-03-13 18:28:35

回答

-1

人們可以包括聚結功能是這樣的:

select distinct CAST(w.work_area AS CHAR(4)) || s.code_id as WATT 
from sys_code s, work_area_master w 
where s.code_type = '590' 
and (CAST(w.work_area AS CHAR(4)) || s.code_id) in (
select substr(coalesce(misc_flags," "), 1,6) 
from sys_code 
where code_type = 'STA' 
); 
+1

不要鼓勵使用隱式聯接的SQL反模式。在這種情況下,看起來他有一個交叉連接,這可能是也可能不是他想要的,下一個維護它的人不知道它是一個錯誤還是故意的。如果稍後的更改添加和添加code_type,這是特別危險的。 – HLGEM 2013-03-13 19:08:26

+0

我同意你的HLGEM。然而,如果這是程序員的故意的意圖,一些交叉連接可以被完全實現。這就是爲什麼我堅信最好的做法之一是對代碼進行評論,而不是讓其他人瞭解作者創建這樣的代碼的意圖。 – Octopus 2013-03-13 19:12:26

+2

如果你使用了明確的連接,你只能寫一個交叉連接。這就是爲什麼如果你打算進行暗示加入是一個非常糟糕的想法,原因之一是你的意圖不明確。即使你評論,評論往往過時,許多開發人員都不會意識到它仍然是有針對性的。如果你使用代碼,意圖總是很清楚。 – HLGEM 2013-03-13 19:17:13

1

不相容原理(即,A或〜A是同義反復)不適每當A可以是NULL。當存在可爲空的字段時,應用三個有價值的loigc,並且必須將排除原則修改爲(A或〜A或A爲NULL)。

1
SELECT DISTINCT 
    CAST(w.work_area AS CHAR(4)) || s.code_id AS what 
FROM sys_code s 
JOIN work_area_master w ON 1=1 
WHERE s.code_type = '590' 
AND EXISTS (
    SELECT * FROM sys_code xx 
    WHERE xx.code_type = 'STA' 
    AND substr(xx.misc_flags, 1,6) = CAST(w.work_area AS CHAR(4)) || s.code_id 
    ); 

腳註:我故意用JOIN ... ON 1=1語法提請注意一個事實,即原始查詢甚至沒有一個聯接條件(除了一個在相關 IN子)

+1

如果您的意思是交叉連接,請使用CROSS JOIN語法編寫一個。不加入1 = 1 – HLGEM 2013-03-13 19:19:12

+0

爲什麼?這一個更突出(我還不知道是否OP是打算做一個carhesian產品,除了子查詢) – wildplasser 2013-03-13 19:24:14

+0

'EXISTS' >>'IN''。我冒昧地把它作爲一個合適的'CROSS JOIN'--我希望你能和你在一起。 – 2013-03-13 19:24:41

0

的檢查sys_codework_area_master的組合是否有效,實際上JOIN條件。

而且使用的EXISTS代替IN,以避免與NULL@wilplasser already provided問題:

SELECT DISTINCT 
     CAST(w.work_area AS CHAR(4)) || s.code_id AS what 
FROM sys_code s 
JOIN work_area_master w ON EXISTS (
      SELECT 1 
      FROM sys_code x 
      WHERE x.code_type = 'STA' 
      AND substr(x.misc_flags, 1,6) 
       = CAST(w.work_area AS CHAR(4)) || s.code_id 
     ) 
WHERE s.code_type = '590' ; 

有關問題與NOT INNULL的詳細說明,請參閱本closely related question on dba.SE