복붙노트

[SQL] SQL NOT IN이 작동하지 않습니다

SQL

SQL NOT IN이 작동하지 않습니다

나는 두 개의 데이터베이스, 재고를 보유하고 다른 하나는 기본 데이터베이스의 기록의 일부를 포함하는 다른 있습니다.

다음 SQL 문은 작동하지 않습니다 :

SELECT  stock.IdStock
        ,stock.Descr       
FROM    [Inventory].[dbo].[Stock] stock
WHERE   stock.IdStock NOT IN
        (SELECT foreignStockId FROM
         [Subset].[dbo].[Products])

이 작동하지 않습니다하지에. NOT 제거하면 두 데이터베이스에있는 올바른 결과, 즉 제품을 제공합니다. 그러나 사용하여 NOT IN은 전혀 결과를 반환하지 않습니다.

나는 무엇, 어떤 아이디어를 잘못하고있는 중이 야?

해결법

  1. ==============================

    1.

    SELECT foreignStockId
    FROM   [Subset].[dbo].[Products]  
    

    아마 NULL을 반환합니다.

    어떤 널 (NULL) 값을 NOT 목록에있는 경우 NOT IN 쿼리는 모든 행을 반환하지 않습니다. 명시 적으로 아래와 같이 null가 아닌 사용하여 제외 할 수 있습니다.

    SELECT stock.IdStock,
           stock.Descr
    FROM   [Inventory].[dbo].[Stock] stock
    WHERE  stock.IdStock NOT IN (SELECT foreignStockId
                                 FROM   [Subset].[dbo].[Products]
                                 WHERE  foreignStockId IS NOT NULL) 
    

    또는 NOT 대신 EXISTS 사용하여 재 작성.

    SELECT stock.idstock,
           stock.descr
    FROM   [Inventory].[dbo].[Stock] stock
    WHERE  NOT EXISTS (SELECT *
                       FROM   [Subset].[dbo].[Products] p
                       WHERE  p.foreignstockid = stock.idstock) 
    

    뿐만 아니라 의미를 가지고 같은 당신이 원하는 것을 NOT EXISTS에 대한 실행 계획은 여기에서 보았다 종종 간단하다.

    행동의 차이에 대한 이유는 SQL에 사용되는 3 개 치 논리까지입니다. 술어는 참, 거짓 또는 알 수 없음으로 평가할 수 있습니다.

    절은 행의 순서를 True로 평가해야 반환되는하지만 아래에 설명 된 바와 같이 NULL가있는 경우이 NOT IN 불가능합니다.

    'A'NOT IN ( 'X'은, 'Y', NULL)이 동등 'A'<> 'X'및 'A'<> 'Y'및 'A'<>을 NULL)

    3 개 치 논리에 대한 진실을 테이블 당 알 수없는에 충실하고 진실과 알 수없는 평가합니다.

    다음 링크는 다양한 옵션의 성능에 대한 몇 가지 추가 논의가있다.

  2. ==============================

    2.NOT IN이없는 작업을 수행하는 경우, 당신은 항상 왼쪽이 가입 할 시도 할 수 있습니다. NULL 인 조인 된 테이블의 값 중 하나를 사용하여 WHERE이어서 필터. 다만, 당신에 의해 결합 된 값은 NULL 값을 포함하지 않습니다.

    NOT IN이없는 작업을 수행하는 경우, 당신은 항상 왼쪽이 가입 할 시도 할 수 있습니다. NULL 인 조인 된 테이블의 값 중 하나를 사용하여 WHERE이어서 필터. 다만, 당신에 의해 결합 된 값은 NULL 값을 포함하지 않습니다.

  3. ==============================

    3.또한 이러한 문제를 해결하기 위해 케이스 절을 사용할 수 있습니다

    또한 이러한 문제를 해결하기 위해 케이스 절을 사용할 수 있습니다

    SELECT  stock.IdStock
            ,stock.Descr        
    FROM    [Inventory].[dbo].[Stock] stock
    WHERE   (Case when stock.IdStock IN
            (SELECT foreignStockId FROM
            [Subset].[dbo].[Products]) then 1 else 0 end) = 0 
    

    이 구문은 SQL 서버, 오라클과 포스트 그레스에서 작동

  4. from https://stackoverflow.com/questions/5231712/sql-not-in-not-working by cc-by-sa and MIT license