2011-12-11 5 views
55

나는이 쿼리를 실행하려고 해요 :PostgreSQL의 'NOT IN'및 하위 쿼리

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11 
AND mac NOT IN (select consols.mac from consols) 

을하지만 어떤 결과를 얻을 수 없습니다. 나는 그것을 테스트했고 구문에 잘못된 것이 있다는 것을 알고있다. MySQL에서는 이러한 쿼리가 완벽하게 작동합니다. macconsols 테이블에 존재하지 않지만 여전히 결과를 제공하지 않는 행을 추가했습니다. NOT IN 사용하는 경우

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11 
AND mac NOT IN (
    SELECT mac 
    FROM consols 
    WHERE mac IS NOT NULL -- add this 
) 
+4

'consols.mac' 열이 NULL이거나 NOT NULL입니까? –

답변

96

당신이 값이되지 않도록해야하지 사용하여 NULL입니다. 당신은 또한 LEFT를 사용할 수

SELECT mac, creation_date 
FROM logs lo 
WHERE logs_type_id=11 
AND NOT EXISTS (
    SELECT * 
    FROM consols nx 
    WHERE nx.mac = lo.mac 
); 
+2

주 :'In (...)'은 항상 NULL (그리고 중복)을 제거하기 때문에 하위 쿼리의'WHERE mac IS NOT NULL' 절은 필요하지 않습니다. 집합에 NULL을 포함 할 수 없기 때문에 – wildplasser

+3

@wildplasser 나는 그것에 대해 몰라요. 'IS NOT NULL '을 추가 할 때까지는 저에게 효과가 없었습니다. 중첩 된'SELECT'는 몇 개의'NULLS'을 반환하고, 그것은'IN (SELECT ...) '을 트리핑하고있었습니다. – robins35

+1

'IS NOT NULL'이 왜이 문제를 일으키는 지에 대한 설명에 크게 감사 할 것입니다. – mbarkhau

25

, 당신은 또한 자동으로 null이 사건을 처리하는 존재하지 고려해야합니다

+1

또한'NOT EXISTS'와'... NOT IN'을 사용할 때 막대한 성능 손실이 발생합니다. – IcanDivideBy0

+1

@ IcanDivideBy0 대부분 동일한 쿼리 계획을 생성합니다. 테스트 해 봤니? – wildplasser

6

은 가입과 NULL 조건입니다 :

SELECT 
    mac, 
    creation_date 
FROM 
    logs 
    LEFT JOIN consols ON logs.mac = consols.mac 
WHERE 
    logs_type_id=11 
AND 
    consols.mac IS NULL; 

는 "맥"컬럼에 인덱스가 성능을 향상시킬 수 있습니다.