Search

REMINDER 05-01. 조인 조건의 테이블과 컬럼을 정확히 연결하자

상황: 주문번호 1001에 해당하는 회원 닉네임과 매장명을 조회한다. 실제 기본 테이블 startdbpg.tr_ord, startdbpg.ms_mbr, startdbpg.ms_shop으로 확인한 사례다.

BAD SQL — 매장 컬럼을 자기 자신과 비교

SELECT o.ord_no, m.nick_nm, s.shop_nm FROM startdbpg.tr_ord o JOIN startdbpg.ms_mbr m ON m.mbr_id = o.mbr_id JOIN startdbpg.ms_shop s ON s.shop_id = s.shop_id -- 주문과 매장을 연결하지 않는 조건 WHERE o.ord_no = 1001;
SQL
복사

GOOD SQL — 주문의 매장 ID와 매장의 매장 ID를 연결

SELECT o.ord_no, m.nick_nm, s.shop_nm FROM startdbpg.tr_ord o JOIN startdbpg.ms_mbr m ON m.mbr_id = o.mbr_id JOIN startdbpg.ms_shop s ON s.shop_id = o.shop_id WHERE o.ord_no = 1001;
SQL
복사
실데이터 검증 결과: 주문번호 1001은 실제 존재하며, 매장 테이블에는 300건이 있다. 위 조건으로 조회한 결과 BAD는 300건, GOOD은 1건이었다. BAD는 주문과 매장을 연결하지 않으므로 일치 회원의 주문 1건에 매장 300건이 모두 결합되었다.
건수 검증 SQL
SELECT 'BAD' AS sql_type, COUNT(*) AS cnt FROM startdbpg.tr_ord o JOIN startdbpg.ms_mbr m ON m.mbr_id = o.mbr_id JOIN startdbpg.ms_shop s ON s.shop_id = s.shop_id WHERE o.ord_no = 1001 UNION ALL SELECT 'GOOD' AS sql_type, COUNT(*) AS cnt FROM startdbpg.tr_ord o JOIN startdbpg.ms_mbr m ON m.mbr_id = o.mbr_id JOIN startdbpg.ms_shop s ON s.shop_id = o.shop_id WHERE o.ord_no = 1001;
SQL
복사

핵심

•
s.shop_id = s.shop_id는 매장 ID가 NULL이 아닌 행에서 항상 참이어서 두 테이블 간 관계를 제한하지 못한다. 이런 조건은 사실상 불필요한 카티션 곱(Cartesian Product)을 만들어 조회 건수를 증폭시킬 수 있다. JOIN ON 절은 실제로 연결해야 할 테이블의 컬럼을 비교하는지 확인하자.
💡
참고·예외
•
자기 비교 col = col은 컬럼이 NULL이면 참이 아니다. 따라서 모든 데이터에서 완전한 CROSS JOIN과 동일하다고 단정할 수는 없다. 이 사례는 특정 주문에서 측정된 결과이며 다른 주문번호 또는 데이터에 따라 반환 행 수는 달라질 수 있다. SQL이 정상적으로 실행되어도 업무 관계가 올바른지는 별도로 검증해야 한다.