Search

[필수:정합]NULL 포함 NOT IN

BAD: 0 rows(5건 누락)

NULL 포함 NOT IN 사용
SELECT c.base_dt FROM startdbpg.cm_base_dt c WHERE c.base_dt BETWEEN '2025-01-23' AND '2025-01-30' AND c.base_dt NOT IN ( SELECT o.pkup_dtm::date FROM startdbpg.tr_ord_big o ) ORDER BY c.base_dt ;
SQL
복사
SQL 결과 보기
•
아직 픽업하지 않은 주문은 pkup_dtm이 NULL입니다.
•
x NOT IN (1, 2, NULL)은 x <> 1 AND x <> 2 AND x <> NULL과 같습니다. x <> NULL은 절대 참이 되지 않으므로, NULL이 하나라도 있으면 결과는 0건입니다.
•
지금은 맞게 나오던 SQL도, 데이터에 NULL이 하나 생기는 순간 0건이 됩니다.

GOOD: 5 rows(정상)

① NOT EXISTS 등으로 제외 조건 처리
SELECT c.base_dt FROM startdbpg.cm_base_dt c WHERE c.base_dt BETWEEN '2025-01-23' AND '2025-01-30' AND NOT EXISTS( SELECT o.pkup_dtm::date FROM startdbpg.tr_ord_big o WHERE o.pkup_dtm >= c.base_dt AND o.pkup_dtm < c.base_dt + interval '1' day -- 성능을 위해 전체 조회 범위를 한 번 더 지정 AND o.pkup_dtm >= '2025-01-23' AND o.pkup_dtm < '2025-01-30'::DATE + interval '1' day ) ORDER BY c.base_dt ;
SQL
복사
SQL 결과 보기
② EXCEPT 방식
SELECT c.base_dt FROM startdbpg.cm_base_dt c WHERE c.base_dt BETWEEN '2025-01-23' AND '2025-01-30' EXCEPT SELECT DISTINCT o.pkup_dtm::date FROM startdbpg.tr_ord_big o WHERE o.pkup_dtm >= '2025-01-23' AND o.pkup_dtm < '2025-01-30'::DATE + interval '1' day ORDER BY 1 ;
SQL
복사
SQL 결과 보기
•
NULL 결과가 포함된 서브쿼리는 NOT EXISTS 또는 EXCEPT로 처리합니다.
•
①의 서브쿼리 아래 두 줄(전체 조회 범위)은 결과에는 영향이 없고, 성능을 위해 추가한 조건입니다.
💡

KEY POINT

•
NOT IN 서브쿼리에 NULL이 하나라도 있으면 결과는 0건입니다.
•
제외 조건은 NOT EXISTS로 씁니다. 차집합이 필요하면 EXCEPT를 씁니다.
•
NULL이 들어올 수 있는 컬럼이면, 지금 결과가 맞아도 NOT IN을 쓰지 않습니다.
✏️

TIP. NOT IN을 꼭 써야 한다면

•
서브쿼리에 WHERE o.pkup_dtm IS NOT NULL을 넣어 NULL을 제외합니다.
•
다만 빠뜨리기 쉬우니, 제외 조건은 NOT EXISTS를 기본으로 씁니다.