it-source

SQL이 작동하지 않음

criticalcode 2023. 4. 11. 22:05
반응형

SQL이 작동하지 않음

2개의 데이터베이스가 있습니다.하나는 인벤토리를 보관하고 다른 하나는 프라이머리 데이터베이스의 레코드 서브셋을 보관합니다.

다음 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을 사용해도 결과는 전혀 반환되지 않습니다.

내가 뭘 잘못하고 있는 거지? 생각나는 거 없어?

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

아마 a를 반환할 것이다.NULL.

A NOT IN쿼리는 행이 있는 경우 행을 반환하지 않습니다.NULL는 다음 목록에 존재합니다.NOT IN가치.다음을 사용하여 명시적으로 제외할 수 있습니다.IS NOT 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,False, 또는Unknown.

A WHERE절은 평가해야 합니다.True행이 반환되도록 하기 위해서입니다만, 이 조작은 할 수중에 없습니다.NOT IN언제NULL아래 설명과 같이 존재합니다.

'A' NOT IN ('X','Y',NULL)와 동등하다'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)

  • 'A' <> 'X' =True
  • 'A' <> 'Y' =True
  • 'A' <> 특수 =Unknown

True AND True AND Unknown까지 평가하다.Unknown진실표에 따라 세 가지 가치 있는 논리를 제시합니다.

다음 링크에서는 다양한 옵션의 성능에 대해 추가로 설명합니다.

NOT IN이 작동하지 않으면 항상 LEFT JOIN을 시도할 수 있습니다.그런 다음 조인된 테이블의 값 중 하나(NULL)를 사용하여 WHERE 기준으로 필터링합니다. 단, 조인한 에 NULL 값이 포함되어 있지 않습니다.

2센트 더하기:

SQL Server에서 잘못된 결과를 반환하는 것을 본 적이 있습니다.not exists그리고.left join- 손상된 데이터베이스에 있습니다.관련된 테이블에서 DBCC CHECKTABLE을 실행하여NOT IN실행 계획을 쿼리하고 관련 인덱스를 재구축하면 도움이 됩니다.

케이스 절을 사용하여 이러한 문제를 해결할 수도 있습니다.

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 Server, Oracle 및 postgres에서 작동합니다.

언급URL : https://stackoverflow.com/questions/5231712/sql-not-in-not-working

반응형