2013-03-13 68 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