복붙노트

[SQL] 결과가 반환 SQL은 "여기서하지 하위 쿼리 선택"

SQL

결과가 반환 SQL은 "여기서하지 하위 쿼리 선택"

면책 조항 : 나는 문제를 (내가 생각하는) 알아 낸,하지만 난 (쉽게) 어디서나 찾을 수 없기 때문에 스택 오버플로이 문제를 추가하고 싶었다. 또한, 누군가가 나보다 더 나은 대답을 할 수도 있습니다.

나는 하나 개의 테이블 "일반적인"가 다른 여러 테이블을 참조하는 데이터베이스가 있습니다. 나는 (즉, 다른 테이블의 아무런 언급이 없었다) 고아가 된 공통 테이블에 기록하는 것을보고 싶었다.

나는이 쿼리를 실행 :

select *
from Common
where common_id not in (select common_id from Table1)
and common_id not in (select common_id from Table2)

나는 분리 된 레코드가 있다는 것을 알고 있지만 레코드가 반환되지 않았다. 왜?

(이 중요한 경우에 SQL Server는 것입니다.)

해결법

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

    1.최신 정보:

    최신 정보:

    내 블로그에이 기사를 자세히 방법의 차이를 설명 :

    이러한 쿼리를 수행하는 세 가지 방법이 있습니다 :

    table1.common_id이 널 (NULL)이 아닌 경우, 모든 쿼리는 의미 적으로 동일합니다.

    이 널 (NULL) 인 경우, NOT IN은 IN (및 따라서, NOT IN) 반환 NULL 때문에 값이 NULL을 포함하는 목록에서 아무것도 일치하지 않을 때, 다르다.

    이 혼동 될 수 있지만, 우리는이에 대한 대체 구문을 기억하면 더 분명 될 수 있습니다 :

    common_id = ANY
    (
    SELECT  common_id
    FROM    table1 t1
    )
    

    이 조건의 결과는 목록 내의 모든 비교의 부울 제품입니다. 물론, 하나의 NULL 값도 전체 결과 NULL를 렌더링하는 NULL 결과를 얻을 수 있습니다.

    우리는 값 중 적어도 하나가 NULL이기 때문에 common_id는이 목록에서 아무것도 같지 않은 것을 확실히 말할 수 없습니다 않았다.

    우리는 이러한 데이터가 있다고 가정 :

    common
    
    --
    1
    3
    
    table1
    
    --
    NULL
    1
    2
    

    왼쪽 / 가입 NULL IS 및 NOT 3을 반환합니다 EXISTS, NOT IN (항상 하나 FALSE 또는 NULL로 평가하기 때문에) 아무 것도 반환하지 않습니다.

    MySQL의에서는 비 널 열의 경우 좌 / IS NULL 가입 NOT IN NOT 존재보다 약간 (수 퍼센트)보다 효율적이다. 컬럼이 널 (NULL) 인 경우, NOT 가장 효율적인 (다시,별로)이다 존재한다.

    오라클, 모든 세 개의 쿼리는 같은 계획 (가입 방지)을 얻을 수 있습니다.

    SQL Server에서 NOT IN / NOT 좌 가입 이후 /입니다보다 효율적으로 EXISTS NULL이 옵티 마이저에 의해 가입 방지에 최적화되지 않을 수있다.

    PostgreSQL의에서 좌 / NULL IS 가입 및 NOT NOT IN보다 더 효율적 EXISTS NOT IN는 해시 하위 계획 사용하는 반면 (또는 일반 하위 계획을 서브 쿼리 해시에 너무 큰 경우), 그들은 안티 가입에 최적화 된 사인 인

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

    2.당신은 세상이 두 값 부울 장소가 될하려는 경우, 당신은 널 (세 번째 값)의 경우 스스로를 방지해야합니다.

    당신은 세상이 두 값 부울 장소가 될하려는 경우, 당신은 널 (세 번째 값)의 경우 스스로를 방지해야합니다.

    목록 측에 널 (null)을 허용 조항 쓰지 마십시오. 그들을 필터링!

    common_id not in
    (
      select common_id from Table1
      where common_id is not null
    )
    
  3. ==============================

    3.표 1 또는 표 2는 common_id에 대한 몇 가지 널 값이 있습니다. 대신이 쿼리를 사용합니다 :

    표 1 또는 표 2는 common_id에 대한 몇 가지 널 값이 있습니다. 대신이 쿼리를 사용합니다 :

    select *
    from Common
    where common_id not in (select common_id from Table1 where common_id is not null)
    and common_id not in (select common_id from Table2 where common_id is not null)
    
  4. ==============================

    4.

    select *
    from Common c
    where not exists (select t1.commonid from table1 t1 where t1.commonid = c.commonid)
    and not exists (select t2.commonid from table2 t2 where t2.commonid = c.commonid)
    
  5. ==============================

    5.그냥 내 머리 위로 떨어져 ...

    그냥 내 머리 위로 떨어져 ...

    select c.commonID, t1.commonID, t2.commonID
    from Common c
         left outer join Table1 t1 on t1.commonID = c.commonID
         left outer join Table2 t2 on t2.commonID = c.commonID
    where t1.commonID is null 
         and t2.commonID is null
    

    나는 몇 가지 테스트를 실행하고 여기에 내 결과였다 w.r.t. @ patmortech의 대답과 @ rexem의 의견.

    표 1 또는 표 2 중 하나가 commonID에 인덱싱되지 않은 경우, 당신은하지만 @ patmortech의 쿼리 (100,000 행 마스터 테이블) 배 빠른 여전히 테이블 스캔을 얻을.

    둘 다 commonID에 색인 경우, 두 개의 테이블 스캔을 얻고 차이는 무시할 수있다.

    모두 commonID에 색인 경우는 1/3 시간에서 쿼리 실행 "을하지 존재".

  6. ==============================

    6.

    SELECT T.common_id
      FROM Common T
           LEFT JOIN Table1 T1 ON T.common_id = T1.common_id
           LEFT JOIN Table2 T2 ON T.common_id = T2.common_id
     WHERE T1.common_id IS NULL
       AND T2.common_id IS NULL
    
  7. ==============================

    7.이제 common_id에 대한 이러한 값을 가정하자 :

    이제 common_id에 대한 이러한 값을 가정하자 :

    Common - 1
    Table1 - 2
    Table2 - 3, null
    

    그것은 다른 테이블의 존재하지 않기 때문에 우리는 반환에 공통의 행을 원한다. 그러나, null가 원숭이 렌치에 발생합니다.

    이 값으로, 쿼리는 동일합니다 :

    select *
    from Common
    where 1 not in (2)
    and 1 not in (3, null)
    

    즉 동일합니다 :

    select *
    from Common
    where not (1=2)
    and not (1=3 or 1=null)
    

    문제가 시작하는 곳이다. 널과 비교할 때, 대답은 알 수 없습니다. 쿼리가 감소 그래서

    select *
    from Common
    where not (false)
    and not (false or unkown)
    

    거짓 또는 알 수없는 알 수 없습니다 :

    select *
    from Common
    where true
    and not (unknown)
    

    사실이 아닌 알 수없는도 알 수 :

    select *
    from Common
    where unknown
    

    결과를 알 수없는 곳에 우리가 어떤 기록을 얻을 수 있도록 WHERE 조건은, 레코드를 반환하지 않습니다.

    이 처리하는 한 가지 방법은. (가) 오히려보다 연산자를 존재 사용하는 것입니다 그것을 행하기보다는 열을 작동하기 때문에 알 수없는 절대 수익률을 존재. (A 행이 하나 존재하거나 그렇지 않습니다 없습니다! 행 수준에서이 널 모호성 전혀)

    select *
    from Common
    where not exists (select common_id from Table1 where common_id = Common.common_id)
    and not exists (select common_id from Table2 where common_id = Common.common_id)
    
  8. ==============================

    8.이것은 나를 위해 일한 :)

    이것은 나를 위해 일한 :)

  9. ==============================

    9.

    select *,
    (select COUNT(ID)  from ProductMaster where ProductMaster.CatID = CategoryMaster.ID) as coun 
    from CategoryMaster
    
  10. ==============================

    10.내가 찾는했다 어디 예를했고, 하나 개의 테이블이 이중으로 값을 유지하기 때문에, 문자열로, 다른 하나는, 그들이 일치하지 (또는 캐스트없이 일치하지) 것입니다. 하지만 NOT IN. SELECT ... 같이 ... 일했다. 이상한,하지만 난 경우 다른 사람의 만남이 간단한 수정 프로그램을 공유하는 것이라고 생각.

    내가 찾는했다 어디 예를했고, 하나 개의 테이블이 이중으로 값을 유지하기 때문에, 문자열로, 다른 하나는, 그들이 일치하지 (또는 캐스트없이 일치하지) 것입니다. 하지만 NOT IN. SELECT ... 같이 ... 일했다. 이상한,하지만 난 경우 다른 사람의 만남이 간단한 수정 프로그램을 공유하는 것이라고 생각.

  11. from https://stackoverflow.com/questions/1406215/sql-select-where-not-in-subquery-returns-no-results by cc-by-sa and MIT license