SQLD 조인 정리 — 6가지 JOIN, 헷갈리는 지점만 모았다
한 줄 요약 — JOIN은 INNER · LEFT · RIGHT · FULL OUTER · CROSS · SELF 6종류. 각 종류의 결과 집합 차이와 NULL 처리 규칙을 한 번 정리해두면 SQLD 2과목 조인 문제 대부분이 풀린다.
SQLD 2과목 "SQL 기본 및 활용" 영역에서 JOIN은 매 회차 출제되는 핵심 유형이다. 단순히 종류를 외우는 것보다, 각 JOIN이 만들어내는 결과 집합의 차이와 NULL이 어디서 생기는지를 이해해야 답이 보인다. 이 글은 ANSI SQL 표준 문법을 기준으로 Oracle 방언과의 차이까지 한 번에 정리한다.
JOIN의 정의 (ANSI SQL 92/99 기준)
JOIN은 두 개 이상의 테이블에서 공통 컬럼이나 조건을 매개로 행을 결합하는 연산이다. ANSI SQL 92에서 JOIN ... ON 표준 문법이 정착했고, 그 이전의 Oracle 방언 (, 콤마 + WHERE 절 + (+) 외부 조인 표기)은 SQLD 시험에도 계속 등장하므로 두 표기를 모두 알아야 한다.
JOIN을 분류하는 기준은 두 가지다.
- 결과 집합 기준: INNER (교집합) vs OUTER (한쪽 또는 양쪽 전체 보존) vs CROSS (카르테시안 곱)
- 참조 대상 기준: 다른 테이블 조인 vs SELF 조인 (같은 테이블 별칭으로 두 번 사용)
JOIN의 6가지 종류
| 종류 | 결과 집합 | NULL 발생 | 표준 문법 | Oracle 방언 |
|---|---|---|---|---|
| INNER JOIN | 양쪽 매칭 행만 | 없음 | A INNER JOIN B ON … | FROM A, B WHERE A.x = B.x |
| LEFT OUTER JOIN | 왼쪽 전부 + 오른쪽 매칭 | 오른쪽 비매칭 컬럼이 NULL | A LEFT JOIN B ON … | WHERE A.x = B.x(+) |
| RIGHT OUTER JOIN | 오른쪽 전부 + 왼쪽 매칭 | 왼쪽 비매칭 컬럼이 NULL | A RIGHT JOIN B ON … | WHERE A.x(+) = B.x |
| FULL OUTER JOIN | 양쪽 전부 | 양쪽 비매칭 컬럼이 NULL | A FULL OUTER JOIN B ON … | (지원 안 함, UNION으로 우회) |
| CROSS JOIN | 카르테시안 곱 (M × N) | 없음 | A CROSS JOIN B | FROM A, B (조건 없을 때) |
| SELF JOIN | 같은 테이블 두 별칭 결합 | 조인 종류에 따름 | A a1 JOIN A a2 ON … | 동일 |
NATURAL JOIN(같은 이름 컬럼 자동 매칭)도 표준에 있지만 실무·시험 모두 명시적이지 않아서 권장하지 않는다.
예제 코드 (실행 가능, ANSI 표준 우선)
다음 두 테이블을 가정한다.
-- employee 테이블
emp_id | emp_name | dept_id
1 | 김민수 | 10
2 | 이서연 | 20
3 | 박지훈 | 30
4 | 최유진 | NULL
-- department 테이블
dept_id | dept_name
10 | 개발팀
20 | 디자인팀
40 | 인사팀INNER JOIN — 양쪽 매칭만
SELECT e.emp_name, d.dept_name
FROM employee e
INNER JOIN department d
ON e.dept_id = d.dept_id;결과: 김민수/개발팀, 이서연/디자인팀 (2행). 박지훈은 부서 30이 department에 없고, 최유진은 NULL이라 제외.
LEFT OUTER JOIN — 왼쪽 전부 보존
SELECT e.emp_name, d.dept_name
FROM employee e
LEFT JOIN department d
ON e.dept_id = d.dept_id;결과: 김민수/개발팀, 이서연/디자인팀, 박지훈/NULL, 최유진/NULL (4행). employee 전체가 살아남고, 매칭 안 된 dept_name은 NULL.
FULL OUTER JOIN — 양쪽 전부
SELECT e.emp_name, d.dept_name
FROM employee e
FULL OUTER JOIN department d
ON e.dept_id = d.dept_id;결과: 위 LEFT 결과 4행 + 인사팀(dept_id=40)이 NULL/인사팀으로 추가된 5행. Oracle, PostgreSQL, SQL Server는 지원하지만 MySQL 8.x는 미지원이라 UNION으로 LEFT + RIGHT을 합쳐 우회한다.
CROSS JOIN — 카르테시안 곱
SELECT e.emp_name, d.dept_name
FROM employee e
CROSS JOIN department d;결과: 4 × 3 = 12행. 조건 없이 모든 조합을 만든다. 보통 의도적으로 쓰는 경우는 드물고, FROM 절에 콤마만 쓰고 WHERE 조인 조건을 빠뜨리는 실수로 발생한다.
SELF JOIN — 같은 테이블 두 번
-- employee 테이블에 manager_id 컬럼이 있다고 가정
SELECT e.emp_name AS 사원, m.emp_name AS 관리자
FROM employee e
LEFT JOIN employee m
ON e.manager_id = m.emp_id;같은 테이블을 e, m 두 별칭으로 두고 계층 구조를 평탄화한다. SQLD에서 조직도·카테고리 트리 문제로 자주 등장한다.
SQLD 출제 패턴
SQLD는 50문항 중 데이터 모델링의 이해 10문항 + SQL 기본 및 활용 40문항으로 구성된다 (KDATA 공식). JOIN은 2과목 핵심 영역으로 매 회차 출제된다.
자주 나오는 형태는 세 가지다.
- 결과 집합 예측: 주어진 두 테이블에 LEFT/INNER/FULL OUTER 중 하나를 적용했을 때 행 개수를 묻는 유형
- 표준 vs 방언 변환: ANSI
LEFT JOIN을 Oracle(+)표기로, 또는 그 반대로 변환하는 유형 - 함정 NULL: OUTER JOIN 결과에서 NULL이 어떤 컬럼에 생기는지 묻는 유형
회차별 정확한 출제 통계는 KDATA가 공개하지 않는다. 다만 SQL 전문가 가이드(KDATA 공식 수험서)와 합격 후기를 종합하면 JOIN 단독·복합 문제가 보통 회차당 여러 문항으로 등장하는 핵심 출제 영역이다(공식 회차별 문항 수는 비공개).
흔한 함정
1. WHERE 절 vs ON 절 위치
OUTER JOIN에서 매칭되지 않은 쪽의 컬럼을 WHERE에서 필터링하면, 그 행 자체가 통째로 사라져 INNER JOIN과 같아진다.
-- 의도: 부서가 없거나, 있어도 인사팀이 아닌 사원
-- 잘못 1: WHERE에서 dept_name 필터만 → NULL 행도 제거됨
SELECT e.emp_name, d.dept_name
FROM employee e
LEFT JOIN department d ON e.dept_id = d.dept_id
WHERE d.dept_name <> '인사팀'; -- 박지훈, 최유진(NULL)이 사라진다
-- 잘못 2: ON 절에만 조건을 넣어도 인사팀 사원이 dept_name=NULL로 남는다
SELECT e.emp_name, d.dept_name
FROM employee e
LEFT JOIN department d
ON e.dept_id = d.dept_id AND d.dept_name <> '인사팀';
-- LEFT JOIN의 ON 조건은 매칭에만 영향을 주고 왼쪽 행을 제거하지 않으므로
-- 인사팀 소속 사원도 d.dept_name=NULL로 결과에 살아남는다.
-- 올바름: WHERE에 NULL 허용 OR 조건을 명시
SELECT e.emp_name, d.dept_name
FROM employee e
LEFT JOIN department d ON e.dept_id = d.dept_id
WHERE d.dept_name <> '인사팀'
OR d.dept_id IS NULL;2. Oracle (+) 양쪽 동시 사용 불가
Oracle 방언 (+)는 한쪽에만 붙일 수 있다. 양쪽 모두 (+)를 붙이면 문법 오류. FULL OUTER가 필요하면 ANSI FULL OUTER JOIN을 쓰거나 UNION으로 합친다.
3. CROSS JOIN 의도치 않은 발생
FROM A, B, C 처럼 콤마만 쓰고 조인 조건을 빠뜨리면 행 개수가 곱절로 부푼다. 3개 테이블이 각각 100행이면 결과는 1,000,000행. 시험에서도 카르테시안 곱이 발생하는 SELECT의 결과 행 수를 묻는 문제가 나온다.
4. SELF JOIN에서 별칭 누락
같은 테이블을 별칭 없이 두 번 부르면 컬럼 참조 모호성으로 에러. SELF JOIN은 항상 별칭이 필수다.
SQLmate에서 직접 실행
SQLmate iOS·Android 앱은 WASM SQLite 샌드박스를 내장해 위 예제를 실제로 실행하면서 결과를 확인할 수 있다. JOIN은 결과 집합을 머리로만 그리면 헷갈리기 쉬운데, 직접 쿼리를 돌려보면 NULL이 어디서 생기는지가 한눈에 들어온다. 시험일정 카운트다운과 함께 홈에서 앱 받기.
FAQ
Q. INNER JOIN과 EQUI JOIN의 차이가 뭔가요?
EQUI JOIN은 조인 조건이 등호(=)인 모든 JOIN을 통칭하고, INNER JOIN은 결과 집합이 교집합인 JOIN을 가리킵니다. 거의 모든 INNER JOIN이 EQUI JOIN인 형태로 작성되지만, INNER JOIN의 ON 절에 부등호(>, <, BETWEEN)를 쓰면 NON-EQUI JOIN이 됩니다. SQLD에서는 가격대 매칭, 등급 매칭 같은 NON-EQUI JOIN 예제도 종종 등장합니다.
Q. LEFT JOIN과 LEFT OUTER JOIN은 똑같은 건가요?
네, 동일합니다. ANSI SQL 표준에서 OUTER 키워드는 선택 사항이고, LEFT JOIN은 LEFT OUTER JOIN의 축약형입니다. RIGHT, FULL도 마찬가지입니다. 시험 답안에는 둘 중 어느 표기를 써도 정답으로 처리되지만, 가독성을 위해 OUTER를 명시하는 쪽을 권장하는 채점 기준이 있을 수 있어 명시 표기가 안전합니다.
Q. NATURAL JOIN은 시험에 나오나요?
출제 빈도는 낮지만 정의 정도는 알아두는 편이 좋습니다. NATURAL JOIN은 두 테이블의 이름이 같은 컬럼을 자동으로 매칭합니다. 다만 컬럼명이 우연히 같으면 의도하지 않은 조인이 일어나고, 미래에 컬럼 추가로 동작이 바뀔 수 있어 실무에서는 비추천입니다. 시험 문제에서 NATURAL JOIN 결과를 묻는다면 "공통 이름 컬럼이 무엇인지"부터 확인해야 합니다.
Q. JOIN 3개 이상 연결하면 순서가 결과에 영향을 주나요?
INNER JOIN끼리는 결합 법칙이 성립해서 순서가 결과에 영향을 주지 않습니다(옵티마이저가 알아서 최적 순서로 실행). 하지만 OUTER JOIN이 섞이면 순서가 결과를 바꿉니다. A LEFT JOIN B INNER JOIN C와 A LEFT JOIN (B INNER JOIN C)는 다른 결과를 낼 수 있어, 괄호로 의도를 명시하는 게 안전합니다.
마무리
JOIN은 외워서 푸는 영역이 아니라 결과 집합을 그릴 줄 알아야 풀리는 영역이다. 6종류 표를 머리에 넣고, 작은 더미 테이블을 만들어 직접 쿼리를 실행해보는 것이 가장 빠른 길이다. SQLmate는 회차 카운트다운 + 합격률 + WASM SQLite 샌드박스를 한 곳에 모아 시험 준비 흐름을 짧게 만든다.
같이 읽으면 좋은 글
- SQLD 서브쿼리 종류 — 4가지 분류와 실행 차이
- SQLD 윈도우 함수 정리 — OVER 절 한 번에 이해하기
- SQLD 기출문제 — 회차별 유형 분포
- SQLD 시험 — 50문항 90분 구조
- SQLmate 홈 — 시험일정 · 회차별 카운트다운
출처 / 참고
한국데이터산업진흥원(KDATA) dataq.or.kr · SQL 전문가 가이드(공식 수험서) · ANSI SQL 92/99 표준 문서.
합격을 보장하지 않습니다. 본인 준비 상황에 맞춰 판단해 주세요.