BAD: 0 rows(1건 누락)
참조집합 조건을 WHERE에 배치
SELECT t1.mbr_id ,t2.ord_no ,t2.ord_st
FROM startdbpg.ms_mbr_big t1
LEFT OUTER JOIN startdbpg.tr_ord_big t2
ON t2.mbr_id = t1.mbr_id
WHERE t1.mbr_id = 'M01658'
AND t2.ord_st = 'PKUP'
AND t2.ord_dtm >= '2025-01-25'
AND t2.ord_dtm < '2025-01-26'
;
SQL
복사
SQL 결과 보기
•
기준집합은 모두 남길 쪽(LEFT OUTER JOIN의 왼쪽), 참조집합은 붙일 쪽(오른쪽)입니다.
•
조인이 먼저 처리되면, 조건에 맞는 주문이 없는 회원은 주문 컬럼이 NULL로 채워집니다.
•
그다음 WHERE의 t2.ord_st = 'PKUP'을 검사하는데, NULL은 'PKUP'과 같지 않으므로 그 회원 행이 걸러집니다.
•
결국 INNER JOIN과 같은 결과가 됩니다. INNER JOIN이 의도라면 OUTER JOIN이 아닌 INNER JOIN으로 씁니다.
GOOD: 1 rows(정상)
참조집합 조건을 ON에 배치
SELECT t1.mbr_id ,t2.ord_no ,t2.ord_st
FROM startdbpg.ms_mbr_big t1
LEFT OUTER JOIN startdbpg.tr_ord_big t2
ON (t2.mbr_id = t1.mbr_id
AND t2.ord_st = 'PKUP'
AND t2.ord_dtm >= '2025-01-25'
AND t2.ord_dtm < '2025-01-26'
)
WHERE t1.mbr_id = 'M01658'
;
SQL
복사
SQL 결과 보기
•
참조집합의 주문 상태·주문일시 조건을 ON에 두어 해당 기간의 PKUP 주문이 없는 M01658 회원도 기준집합으로 유지합니다. 주문 컬럼은 NULL로 조회됩니다.
KEY POINT
•
LEFT OUTER JOIN에서 참조집합(오른쪽 테이블)의 조건은 ON에 씁니다.
•
WHERE에 쓰면 매칭이 없어 NULL인 행이 걸러져, INNER JOIN과 같은 결과가 됩니다.
•
INNER JOIN 결과가 의도라면 처음부터 INNER JOIN으로 씁니다.
TIP. 주문이 없는 회원만 찾을 때
•
매칭이 없는 행만 골라낼 때는 WHERE t2.mbr_id IS NULL처럼 참조집합 조건을 WHERE에 쓰는 방식도 고려할 수 있습니다.
•
다만 이런 목적이라면 NOT EXISTS로 쓰는 것이 더 일반적이고 의도도 분명합니다.
DEEP DIVE — SQL STARTER for MySQL관련 페이지: [필수:정합]OUTER JOIN 기준집합 필터 위치 오류




