Вопрос

I have this query that will return correctly the values that are part of the IN clause, but when I change it to NOT IN, it does not return anything.
Does anyone have any suggestions?

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'
    );
Это было полезно?

Решение 4

One could include a coalesce function like this:

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'
);

Другие советы

The Exclusion Principle (ie, that A or ~A is a tautology) does NOT apply whenever A may be NULL. When nullable fields exist, three valued loigc applies and the Exclusion Principle must be modified to ( A or ~A or A is NULL).

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
    );

Footnote: I deliberately used the JOIN ... ON 1=1 syntax to draw attention to the fact that the original query did not even have a join condition (except for the one in the correlated IN subquery)

The check whether the combination of sys_code and work_area_master is valid can actually be the JOIN condition.

Also using EXISTS instead of IN to avoid problems with NULL like @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' ;

For a detailed explanation of the problem with NOT IN and NULL, refer to this closely related question on dba.SE.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top