ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Database] SQL JOIN 총정리: INNER/OUTER/SEMI/ANTI/CROSS, NATURAL/USING, UNION
    업무 자동화/Database 2025. 11. 14. 08:57

    요약

    JOIN 목적 여러 테이블의 **관계(키)**를 기준으로 행 결합
    기본 축 INNER(교집합), OUTER(남는 쪽 보존: LEFT/RIGHT/FULL), SEMI/ANTI(존재 유무만), CROSS(카테시안)
    키 문법 JOIN … ON a.key = b.key / USING(key) / NATURAL(동명 컬럼 자동 매칭, 권장 X)
    위험 포인트 ON 누락·항상 참 조건 → CROSS JOIN(카테시안 곱) 발생
    UNION과 차이 JOIN=열(칼럼) 합치기, UNION=행(로우) 합치기
    성능 포인트 선택성 높은 조건 우선, 인덱스·통계 최신화, 불필요 컬럼·중복 제거, 실행계획 확인

     

    1. JOIN 기본: 개념·형태

    1-1. INNER JOIN

    • 정의: 조인 키가 일치하는 행만 반환(교집합).
    • 예시
     
    SELECT a.id, a.name, b.order_id
    FROM customer a
    JOIN orders b
      ON a.id = b.customer_id;

    1-2. OUTER JOIN (LEFT / RIGHT / FULL)

    • 정의: 한쪽 테이블의 모든 행 보존 + 반대쪽 매칭 없을 시 NULL 채움.
    • LEFT OUTER
     
    SELECT a.id, a.name, b.order_id
    FROM customer a
    LEFT JOIN orders b
      ON a.id = b.customer_id;   -- 고객은 모두, 주문 없으면 NULL
    • RIGHT OUTER: LEFT와 반대 개념(가독성 위해 LEFT 선호).
    • FULL OUTER: 양쪽 모두 보존(일부 DBMS 미지원 → UNION 조합 대체).

    1-3. SEMI JOIN / ANTI JOIN (존재 유무 판단)

    • SEMI: “존재하면 1행만” 취급(우항 컬럼 가져오지 않음).
     
    -- 고객 중 ‘주문이 존재하는’ 고객만
    SELECT a.*
    FROM customer a
    WHERE EXISTS (SELECT 1 FROM orders b WHERE b.customer_id = a.id);
    • ANTI: “존재하지 않으면” 반환.
     
    -- 주문이 '없는' 고객
    SELECT a.*
    FROM customer a
    WHERE NOT EXISTS (SELECT 1 FROM orders b WHERE b.customer_id = a.id);

    1-4. CROSS JOIN (카테시안 곱)

    • 정의: 모든 행 × 모든 행 결합(조건 없음).
    • 의도적 사용 외에는 대부분 버그 신호.
     
    SELECT *
    FROM a
    CROSS JOIN b;     -- 또는 JOIN인데 ON 누락 → 같은 효과

     

    2. NATURAL / USING / ON

    방식특징장단점/주의
    ON 임의 컬럼 조합 명시 가독성·명확성 최고, 가장 보편·권장
    USING(col) 양쪽 동일 컬럼명 하나일 때 축약 선택 컬럼 중복 제거(한 번만 노출)
    NATURAL 양쪽 동명 컬럼 전부 자동 매칭 스키마 변경 시 예상치 못한 매칭 위험 → 비권장

    예시

     
    -- ON
    SELECT * FROM a JOIN b ON a.key = b.key;

    -- USING
    SELECT * FROM a JOIN b USING (key);   -- a.key, b.key 중복 노출 방지

    -- NATURAL (지양)
    SELECT * FROM a NATURAL JOIN b;       -- 동명 컬럼 전부 매칭(위험)

     

    3. JOIN과 UNION의 차이(행 vs 열)

    구분JOINUNION / UNION ALL
    결합 축 열(칼럼) 확장 행(로우) 합치기
    전제 공통 키(관계) 같은 컬럼 구조(열 수/타입 호환)
    중복 처리 없음 UNION 중복 제거 / UNION ALL 중복 유지
    활용 예 고객↔주문 결합 2024년 매출 + 2025년 매출 합치기

    예시(UNION)

    SELECT '2024' AS yr, amount FROM sales_2024
    UNION ALL
    SELECT '2025' AS yr, amount FROM sales_2025;

    INTERSECT / EXCEPT는 DBMS별 지원 상이(대체: 세미/안티 조인, IN/NOT IN, EXISTS/NOT EXISTS).

     

    4. 실전 패턴별 예시 모음

    4-1. 1:N 관계(가장 흔한 형태)

    SELECT c.id, c.name, o.order_id, o.amount
    FROM customer c
    JOIN orders o
      ON c.id = o.customer_id;

    5-2. LEFT JOIN + 집계(없으면 0)

     
    SELECT c.id, c.name, COALESCE(SUM(o.amount), 0) AS total_amount
    FROM customer c
    LEFT JOIN orders o
      ON c.id = o.customer_id
    GROUP BY c.id, c.name;

    5-3. SELF JOIN(동일 테이블 내 관계)

     
    -- 직원-관리자 트리
    SELECT e.emp_id, e.emp_name, m.emp_name AS manager_name
    FROM emp e
    LEFT JOIN emp m
      ON e.manager_id = m.emp_id;

    5-4. 조건부 조인(날짜/상태 동시 매칭)

     
    SELECT a.id, a.dt, b.status
    FROM a
    JOIN b
      ON a.id = b.id
     AND a.dt BETWEEN b.start_dt AND b.end_dt
     AND b.status = 'ACTIVE';

    5-5. 반정규화된 키 매핑(코드 테이블)

     
    SELECT o.order_id, d.code_nm AS status_nm
    FROM orders o
    JOIN code_dict d
      ON o.status_cd = d.code_cd;

     

    6. 성능·품질 체크리스트

    • 조인 키 인덱스: 외래키(FK)·조회 키에 인덱스 준비
    • 선택성 높은 조건 우선: 필터 선적용(서브쿼리/CTE 또는 WHERE)
    • 필요 컬럼 최소화: SELECT * 지양, 전송량·메모리 절감
    • 집계 전 중복 방지: 조인 폭발 가능 지점에서 카디널리티 확인
    • 실행계획 습관화: EXPLAIN/통계 갱신(ANALYZE) 주기화
    • ANSI 조인 일원화: , 조인 + WHERE 혼용 지양
    • 테스트 데이터: 0/1/다 케이스 포함 표준 세트 운영
Designed by Tistory.