내부 조인과 외부 조인의 차이: 남는 행·NULL·왼쪽 외부 조인과 오른쪽 외부 조인·SQL 작성법 비교

조인(JOIN)은 두 테이블의 행을 ON으로 지정한 조건(대개 외래 키와 기본 키의 값이 같은 것)으로 조합해 하나의 결과 테이블을 만드는 연산입니다. 내부 조인은 조건에 맞는 짝이 있는 행의 조합만 결과에 남기고, 짝이 없는 행은 어느 테이블의 것이든 사라집니다. 외부 조인은 일치하는 조합에 더해, 지정한 쪽 테이블의 행을 짝이 없어도 남기고 상대 테이블의 열을 NULL로 채웁니다. 왼쪽 테이블의 행을 모두 남기는 것이 왼쪽 외부 조인(LEFT OUTER JOIN), 오른쪽을 남기는 것이 오른쪽 외부 조인(RIGHT OUTER JOIN), 양쪽을 남기는 것이 완전 외부 조인(FULL OUTER JOIN)입니다. '짝이 없는 행도 결과에 내고 싶은가'로 골라 씁니다.

비교 항목내부 조인(INNER JOIN)외부 조인(OUTER JOIN)
결과에 남는 행조인 조건에 맞는 행의 조합만일치하는 조합에 더해, 남기는 쪽으로 지정한 테이블에서 일치하는 짝이 없는 행
짝이 없는 행의 처리왼쪽과 오른쪽 어느 테이블의 행이든 결과에서 사라진다남기는 쪽의 행은 상대 테이블의 열을 NULL로 하여 1행으로 남는다. 남기는 쪽이 아닌 테이블의 행은 사라진다
종류1종류. INNER를 생략하고 JOIN이라고만 써도 된다왼쪽 외부 조인(LEFT), 오른쪽 외부 조인(RIGHT), 완전 외부 조인(FULL)의 3종류. OUTER는 생략해도 된다
SQL 작성 예SELECT … FROM 사원 INNER JOIN 부서 ON 사원.부서ID = 부서.부서IDSELECT … FROM 사원 LEFT OUTER JOIN 부서 ON 사원.부서ID = 부서.부서ID
결과 행 수의 예(사원 4명 중 1명은 부서ID가 NULL, 부서 3개 중 1개는 사원이 없음)3행. 부서ID가 NULL인 사원과 사원이 없는 부서는 나오지 않는다사원 테이블을 남기는 왼쪽 외부 조인에서는 4행(부서ID가 NULL인 사원은 부서명이 NULL이 된다). 양쪽을 남기는 완전 외부 조인에서는 5행
테이블을 쓰는 순서왼쪽과 오른쪽을 바꾸어도 결과 행은 같다(열의 순서는 바뀐다)왼쪽 외부 조인과 오른쪽 외부 조인에서는 어느 테이블을 왼쪽에 쓰느냐에 따라 결과가 바뀐다. A LEFT OUTER JOIN B와 B RIGHT OUTER JOIN A는 같은 행을 반환한다
상대 테이블의 열에 대한 조건ON에 쓰든 WHERE 절에 쓰든 결과는 같다WHERE 절에 쓰면 NULL로 채운 행이 조건을 만족하지 못해 사라지고, 내부 조인과 같은 결과가 되는 경우가 있다. 짝이 없는 행도 남기고 싶을 때는 ON에 쓴다
주요 용도양쪽 테이블에 데이터가 갖추어진 것만 쓰고 싶을 때(주문에 고객 이름을 붙이는 등)짝이 없는 행도 포함해 목록을 만들고 싶을 때(부서가 지정되지 않은 사원도 포함한 사원 목록 등), 짝이 없는 행을 찾고 싶을 때

수치는 대략적인 자릿수 기준이며, 공정 세대와 제품에 따라 달라져요.

상황별 선택 기준

내부 조인
양쪽 테이블에 대응하는 데이터가 있는 행만 필요할 때 씁니다. 예를 들어 주문 목록에 고객 이름을 붙일 때, 고객을 알 수 없는 주문이 필요 없다면 내부 조인입니다.
외부 조인
짝이 없는 행도 빠뜨리지 않고 내고 싶을 때 씁니다. 예를 들어 전체 사원 목록에 부서명을 붙이면서 부서가 지정되지 않은 사원도 남기고 싶을 때는 사원 테이블을 남기는 왼쪽 외부 조인입니다. 외부 조인을 한 뒤 상대 테이블의 기본 키 열이 NULL인 행을 고르면, 한 번도 주문하지 않은 고객처럼 짝이 없는 행을 찾을 수도 있습니다.

자주 묻는 질문

왼쪽 외부 조인과 오른쪽 외부 조인은 어떻게 다른가요?

어느 테이블의 행을 모두 남기느냐만 다릅니다. 왼쪽 외부 조인은 FROM에 먼저 쓴 왼쪽 테이블의 행을, 오른쪽 외부 조인은 나중에 쓴 오른쪽 테이블의 행을 짝이 없어도 남깁니다. A LEFT OUTER JOIN B와 B RIGHT OUTER JOIN A는 같은 행을 반환하므로, 읽기 쉽도록 왼쪽 외부 조인으로 통일해 쓰는 경우도 많습니다.

조인 결과가 원래 테이블보다 행이 많아지는 이유는 무엇인가요?

조인에서는 조건을 만족하는 행의 조합이 하나씩 결과 행이 되기 때문입니다. 조인하는 열의 값이 양쪽 테이블에서 중복되면 조합의 수가 곱셈으로 늘어납니다. 예를 들어 값이 1인 행이 한쪽에 2행, 다른 쪽에 2행 있으면 그 값만으로 2 × 2 = 4행이 됩니다.

조인 조건을 붙이지 않으면 어떻게 되나요?

두 테이블의 모든 행의 조합(곱집합)이 됩니다. 이를 CROSS JOIN이라고 하며, 4행 테이블과 3행 테이블이면 4 × 3 = 12행입니다. ON을 빠뜨리는 등으로 의도치 않게 곱집합을 만들면 결과 행 수가 급격히 늘어나므로 주의가 필요합니다.

NULL끼리는 조인 조건에서 일치하나요?

일치하지 않습니다. SQL에서는 NULL과의 비교가 참이 되지 않으므로, 양쪽 테이블에서 조인하는 열이 NULL인 행끼리도 조합되지 않습니다. 그래서 내부 조인에서는 조인하는 열이 NULL인 행이 결과에서 사라집니다.

이해도 확인

사원 표(사원번호, 이름, 부서ID)에 4개 행이 있고, 부서ID는 차례로 10, 20, 10, NULL이다. 부서 표(부서ID, 부서명)에는 부서ID가 10, 20, 30인 3개 행이 있다. SELECT 사원.이름, 부서.부서명 FROM 사원 INNER JOIN 부서 ON 사원.부서ID = 부서.부서ID의 결과는 몇 행이 되는가?

  1. A3행
  2. B4행
  3. C12행
정답과 해설 보기

정답: A. 3행

INNER JOIN(내부 조인)은 ON의 조건을 만족하는 행의 조합만 결과로 합니다. 부서ID가 10인 사원 2명은 부서 10의 행과, 부서ID가 20인 사원 1명은 부서 20의 행과 조합되므로 결과는 3행입니다. 부서ID가 NULL인 사원은 NULL과의 비교가 참이 되지 않으므로 어느 부서와도 조인되지 않고 결과에서 사라집니다. 또한 사원이 없는 부서 30도 결과에 나오지 않습니다. 4행은 사원 표의 모든 행을 남기는 왼쪽 외부 조인(사원 LEFT OUTER JOIN 부서)의 경우의 행 수입니다. 12행은 조건 없이 모든 조합을 만드는 CROSS JOIN(곱집합)의 4 × 3 = 12행입니다.

사원 표(사원번호, 이름, 부서ID)에 5개 행이 있고, 부서ID는 차례로 10, 20, 10, NULL, NULL이다. 부서 표(부서ID, 부서명)에는 부서ID가 10, 20, 30인 3개 행이 있다. SELECT 부서.부서명, 사원.이름 FROM 부서 LEFT OUTER JOIN 사원 ON 부서.부서ID = 사원.부서ID의 결과는 몇 행이 되는가?

  1. A3행
  2. B4행
  3. C5행
정답과 해설 보기

정답: B. 4행

LEFT OUTER JOIN(왼쪽 외부 조인)은 왼쪽 표(여기서는 부서 표)의 모든 행을 남기고, 오른쪽 표에 일치하는 행이 없으면 오른쪽 열을 NULL로 채워 한 행으로 합니다. 부서 10에는 사원이 2명 있으므로 2행, 부서 20은 1행, 사원이 없는 부서 30은 이름이 NULL인 1행이 되어 합계 4행입니다. 부서ID가 NULL인 사원 2명은 어느 부서와도 일치하지 않고, 남길 대상이 아닌 오른쪽 표의 행이므로 결과에 나오지 않습니다. 내부 조인이라면 부서 30의 행도 사라져 3행입니다. 표의 좌우를 바꾸어 사원 LEFT OUTER JOIN 부서로 하면 사원 5명이 모두 남으므로 5행이 됩니다. 외부 조인에서는 어느 쪽 표의 행을 모두 남기는지 확인하는 것이 중요합니다.

표 R의 열 x의 값은 1, 1, 2, 3의 4개 행, 표 S의 열 x의 값은 1, 1, 2, 4의 4개 행이다. SELECT * FROM R INNER JOIN S ON R.x = S.x의 결과는 몇 행이 되는가?

  1. A2행
  2. B3행
  3. C5행
정답과 해설 보기

정답: C. 5행

조인에서는 조건을 만족하는 행의 조합이 하나씩 결과 행이 됩니다. x = 1에 대해서는 R의 2행과 S의 2행의 모든 조합이 조건을 만족하므로 2 × 2 = 4행, x = 2에 대해서는 1 × 1 = 1행입니다. R의 3과 S의 4는 상대가 없으므로 내부 조인의 결과에 나오지 않습니다. 합계는 4 + 1 = 5행입니다. 2행은 일치하는 값의 종류(1과 2)마다 한 행씩만 생긴다고 생각한 경우의 행 수입니다. 3행은 R의 각 행에 대해 S에 일치하는 값이 있는지만 본 경우(SELECT * FROM R WHERE x IN (SELECT x FROM S) 같은 질의)의 행 수입니다. 조건 없는 곱집합이라면 4 × 4 = 16행이 됩니다. 조인하는 열의 값이 중복되어 있으면 결과 행이 곱셈으로 늘어난다는 점에 주의해야 합니다.

  1. 고객 표(고객ID, 이름)와 주문 표(주문ID, 고객ID, 금액)에서 한 번도 주문하지 않은 고객의 이름을 구하려고 한다. 올바른 SQL 문은?

데이터베이스 기초 문제 풀기

주요 용어 설명

SQL
관계형 데이터베이스에서 표의 정의, 데이터의 검색·추가·갱신·삭제, 권한의 제어 등을 수행하기 위한 표준 언어. ISO/IEC(일본에서는 JIS)로 규격화되어 있다. SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, GRANT 등의 문이 있다.
관계형 데이터베이스(Relational Database)
데이터를 행과 열로 이루어진 표(관계, 릴레이션)로 나타내고, 표끼리를 공통의 값으로 연관 지어 다루는 데이터베이스. RDB라고도 한다. SQL로 질의와 갱신을 수행하며, 기본 키나 외래 키 등의 제약으로 데이터의 정합성을 유지한다.
기본 키(Primary Key)
표 안의 한 행을 유일하게 식별하기 위한 열 또는 열의 조합. 값이 중복되지 않고 NULL을 포함하지 않는다는 제약을 가진다. 행을 유일하게 식별할 수 있는 최소한의 열 조합(후보 키) 중에서 하나를 골라 기본 키로 한다.
외래 키(Foreign Key)
다른 표의 기본 키(또는 유일한 열)를 참조하는 열. 참조 대상에 존재하는 값이나 NULL만 넣을 수 있다는 참조 무결성 제약에 의해, 존재하지 않는 행을 가리키는 데이터가 들어가는 것을 막는다. 참조 대상의 행을 삭제·갱신했을 때의 동작(거부, 연쇄 삭제 등)도 지정할 수 있다.
정규화(Normalization)
관계형 데이터베이스의 표를 열 사이의 함수 종속에 근거하여 분할하고, 같은 사실이 여러 곳에 기록되지 않게 하는 설계 절차. 데이터의 중복을 없애고 갱신 이상·삽입 이상·삭제 이상을 막는다. 제1정규형부터 제3정규형, 보이스-코드 정규형 등의 단계가 있다.
뷰(View)
관계형 데이터베이스에서 SELECT 문에 이름을 붙여 정의하는 가상의 표. 보통은 스스로 데이터를 갖지 않고, 참조할 때마다 원래 표에서 결과를 만든다. 복잡한 질의를 간단하게 하거나, 보여 줄 열이나 행을 좁혀 접근할 수 있는 범위를 제한하는 데 사용한다.

관련 비교