공공부하자개발 · 영어 학습 노트
SQL
SQL 중급서브쿼리·조인·함수·DDL·인덱스0/11 완료
  • 01서브쿼리: 스칼라·인라인 뷰·상관 서브쿼리, DB별 차이
  • 02EXISTS·IN·NOT IN 과 NULL 함정
  • 03조인 심화: INNER·OUTER·SELF·CROSS, Oracle (+)
  • 04집합 연산: UNION·UNION ALL·INTERSECT·MINUS/EXCEPT
  • 05조건 로직: CASE·DECODE·IIF
  • 06NULL 처리 함수
  • 07문자·날짜 함수 DB별 비교
  • 08DDL 과 제약 조건
  • 09인덱스 기초
  • 10집계와 GROUP BY·HAVING
  • 11뷰·시퀀스·자동 증가
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › SQL 중급 › 03 / 11

조인 심화: INNER·OUTER·SELF·CROSS, Oracle (+)

섹션 6진행 0 / 11
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6정리‹ 이전다음 ›

2. 핵심 원리

2.1 INNER JOIN 과 OUTER JOIN

INNER JOIN 은 두 테이블 모두 조인 조건을 만족하는 행만 남깁니다. 한쪽에만 있는 행은 결과에서 완전히 빠집니다. OUTER JOIN 은 한쪽(또는 양쪽) 테이블의 행을 조건이 안 맞아도 남기고, 짝이 없는 자리는 NULL 로 채웁니다.

종류 남기는 쪽 짝 없으면
INNER JOIN 양쪽 다 매칭된 행만 결과에서 제외
LEFT (OUTER) JOIN 왼쪽 테이블 전체 오른쪽 컬럼이 NULL
RIGHT (OUTER) JOIN 오른쪽 테이블 전체 왼쪽 컬럼이 NULL
FULL (OUTER) JOIN 양쪽 테이블 전체 없는 쪽이 NULL
핵심

LEFT 와 RIGHT 는 FROM 절에서 어느 테이블을 먼저 적었느냐가 아니라, LEFT·RIGHT 키워드 기준으로 왼쪽·오른쪽 테이블을 가리킵니다. A LEFT JOIN B 는 A 를 전부 남깁니다.

2.2 ON 과 WHERE 의 차이

ON 절은 "두 테이블을 어떻게 짝지을지"를 정하고, WHERE 절은 "그렇게 만들어진 결과에서 어떤 행만 남길지"를 정합니다. INNER JOIN 에서는 둘의 차이가 결과에 드러나지 않지만, OUTER JOIN 에서는 완전히 다른 결과를 만듭니다.

LEFT JOIN 뒤에 WHERE 절로 오른쪽 테이블 컬럼에 조건을 걸면, 짝이 없어 NULL 로 채워진 행은 그 조건을 통과하지 못합니다. NULL > 400 은 참도 거짓도 아닌 UNKNOWN 이라 WHERE 절이 그 행을 걸러 버립니다. 결과적으로 LEFT JOIN 을 썼는데도 짝 없는 행이 사라져 INNER JOIN 과 똑같아집니다.

주의

이 함정을 피하려면 오른쪽 테이블 조건을 WHERE 가 아니라 ON 절 안에 같이 넣습니다. ON a.code = b.code AND b.col > 400 처럼 쓰면 조건이 "짝짓기 규칙"의 일부가 되어, 조건에 안 맞아도 왼쪽 행은 NULL 짝과 함께 살아남습니다.

2.3 조인 후 행 수 뻥튀기(1:N)

부서 하나에 직원이 여러 명이면, 부서와 직원을 조인한 결과는 부서 수가 아니라 직원 수만큼 나옵니다. 부서 이름이 직원 수만큼 반복되는 것은 정상입니다. 문제는 여기에 1:N 관계인 다른 테이블을 하나 더 조인할 때 생깁니다.

직원에 주문을 LEFT JOIN 하면, 주문이 여러 건인 직원은 행이 주문 건수만큼 늘어납니다. 이 상태에서 부서별로 COUNT(*) 를 세면 직원 수가 아니라 "직원 x 주문 건수"가 섞인 값이 나와 실제 인원보다 부풀려집니다.

핵심

조인을 여러 번 거친 뒤 개수를 셀 때는 COUNT(*) 대신 COUNT(DISTINCT 기준컬럼) 을 쓰는 습관이 안전합니다. 3절 예제에서 부풀려진 값과 바로잡은 값을 나란히 확인합니다.

2.4 SELF JOIN

같은 테이블을 별칭만 다르게 해서 두 번 이상 조인하는 방식입니다. 조직도처럼 한 테이블 안에 "나"와 "내 상위 항목"이 같이 들어 있는 구조(직원 테이블의 관리자 id)에 씁니다. 문법은 일반 조인과 같고, 별칭으로 같은 테이블의 서로 다른 역할을 구분할 뿐입니다.

관리자가 없는 최상위 직원(대표)도 결과에 남기려면 INNER JOIN 이 아니라 LEFT JOIN 으로 self join 해야 합니다. 관리자 id 가 NULL 인 행은 INNER JOIN 에서는 통째로 빠집니다.

2.5 CROSS JOIN

두 테이블의 모든 행 조합을 만드는 조인입니다. ON 조건이 없고, 결과 행 수는 두 테이블 행 수의 곱입니다. 부서 6개 x 분기 4개면 24행이 나오는 식으로, 보고서의 빈 틀이나 달력처럼 "가능한 모든 조합"이 먼저 필요한 화면에 씁니다.

CROSS JOIN 은 조건 없이 곱집합을 만들기 때문에, 큰 테이블끼리 실수로 CROSS JOIN 하면 행 수가 순식간에 커집니다. ON 을 빠뜨려서 의도치 않게 CROSS JOIN 이 되는 실수는 5절에서 다룹니다.

2.6 비등가 조인(Non-equi Join)

조인 조건이 = 가 아니라 BETWEEN·>·< 같은 범위·부등호인 조인입니다. 값 하나가 어느 구간에 속하는지 찾을 때 씁니다. 대표적인 예가 급여를 등급표의 하한·상한 범위(e.sal BETWEEN g.lo AND g.hi)와 맞추는 조회입니다. 등가 조인처럼 인덱스를 그대로 타지 못하는 경우가 많아, 등급표처럼 행 수가 적은 테이블에 주로 씁니다.

2.7 성능 메모: 조인 순서와 드라이빙 테이블

조인 순서는 옵티마이저가 대부분 알아서 정하지만, 힌트나 통계가 부정확하면 개발자가 의도한 순서와 달라질 수 있습니다. 먼저 읽는 테이블을 드라이빙 테이블이라 부르고, 보통 조건으로 행 수를 많이 줄이는 테이블을 드라이빙으로 삼는 편이 유리합니다.

조인 컬럼(ON 절에 쓰는 컬럼)에 인덱스가 없으면 조인마다 전체 스캔이 반복될 수 있어, FK 컬럼에는 인덱스를 붙이는 것이 기본입니다. Nested Loop·Hash·Merge 같은 실제 조인 방식과 실행 계획 읽는 법은 대용량·배치 06 에서 다룹니다.

핵심 원리
  • 2.1 INNER JOIN 과 OUTER JOIN
  • 2.2 ON 과 WHERE 의 차이
  • 2.3 조인 후 행 수 뻥튀기(1:N)
  • 2.4 SELF JOIN
  • 2.5 CROSS JOIN
  • 2.6 비등가 조인(Non-equi Join)
  • 2.7 성능 메모: 조인 순서와 드라이빙 테이블
이전 섹션1 왜 배우는가2 / 6다음 섹션3 코드 예제