[SQLD] 06. 표준 조인 (JOIN)

TJK·2025년 7월 25일
1

표준 조인 (JOIN)

조인(JOIN)은 관계형 데이터베이스의 핵심으로, 여러 테이블에 흩어져 있는 데이터를 하나의 테이블처럼 합쳐서 조회하는 기능임. 정규화를 통해 분리된 테이블들의 관계를 이용하여 의미 있는 데이터 집합을 생성함.


1. 조인의 기본 원리: 카티션 곱 (Cartesian Product)

조인의 가장 근본적인 개념은 카티션 곱임. 이는 조인에 참여하는 모든 테이블의 각 행을 서로 가능한 모든 조합으로 연결하는 것을 의미함.

  • FROM table1, table2 또는 FROM table1 CROSS JOIN table2 와 같이 조인 조건을 명시하지 않으면 발생함.
  • A 테이블의 행이 m개, B 테이블의 행이 n개일 때, 결과는 m x n 개의 행을 가짐.
  • 이렇게 생성된 결과는 대부분 의미 없는 데이터의 조합이므로, 유효한 연결고리(조인 조건)를 통해 필터링하는 과정이 필수적임.
/*
 * -- 조인 조건이 없는 경우: 3개 부서 * 4명 사원 = 12개 행의 카티션 곱 발생
 * CROSS JOIN 키워드를 명시적으로 사용할 수도 있음.
 */
SELECT
    d.name AS department_name,
    e.name AS employee_name
FROM
    Department d, Employee e;

2. 내부 조인 (INNER JOIN)

INNER JOIN은 두 테이블에서 조인 조건을 만족하는(짝이 맞는) 행들만 결과에 포함시키는 가장 일반적인 조인 방식임.

2.1 ANSI 표준 INNER JOIN 문법

  • FROM table1 INNER JOIN table2 ON (조인 조건) 형태로 작성함.
  • ON 절에 두 테이블을 연결하는 컬럼이 동일하다는 조건을 명시함.
  • INNER 키워드는 생략 가능하여 JOIN만으로도 INNER JOIN으로 동작함.
/*
 * -- Post와 User 테이블을 INNER JOIN --
 * Post 테이블의 user_id와 User 테이블의 user_id가 일치하는 행만 연결하여
 * 게시물 내용과 작성자 이름을 함께 조회함.
 */
SELECT
    p.content,
    u.name
FROM
    Post p
INNER JOIN
    User u ON p.user_id = u.user_id;

2.2 3개 이상 테이블 조인

  • JOIN을 연쇄적으로 사용하여 여러 테이블을 연결할 수 있음.
  • 어떤 테이블을 먼저 조인하는지에 따라 성능에 영향을 줄 수 있지만, INNER JOIN의 경우 결과 집합은 논리적으로 동일함.
-- Comment, Post, User 세 테이블을 조인하여 댓글 내용, 원본 게시물 내용, 댓글 작성자 이름을 조회
SELECT
    c.comment_text,
    p.content AS post_content,
    u.name AS commenter_name
FROM
    Comment c
INNER JOIN Post p ON c.post_id = p.post_id -- 1. Comment와 Post 연결
INNER JOIN User u ON c.user_id = u.user_id; -- 2. Comment와 User 연결

3. 외부 조인 (OUTER JOIN)

OUTER JOIN은 조인 조건을 만족하지 않더라도, 기준이 되는 테이블의 모든 행을 결과에 포함시키는 조인 방식임. 짝이 없는 상대 테이블의 컬럼은 NULL로 채워짐.

조인 종류설명
LEFT OUTER JOIN왼쪽(먼저 선언된) 테이블의 모든 행을 포함함.
RIGHT OUTER JOIN오른쪽(나중에 선언된) 테이블의 모든 행을 포함함.
FULL OUTER JOIN양쪽 테이블의 모든 행을 포함함.
/*
 * -- LEFT OUTER JOIN 예시 --
 * User 테이블(왼쪽)을 기준으로, 모든 사용자를 조회함.
 * Profile을 작성한 사용자는 프로필 정보를, 작성하지 않은 사용자는 프로필 정보 컬럼을 NULL로 표시함.
 */
SELECT
    u.name,
    p.bio
FROM
    User u
LEFT OUTER JOIN Profile p ON u.user_id = p.user_id;
-- OUTER 키워드는 생략 가능 (LEFT JOIN)

4. 기타 조인

4.1 셀프 조인 (SELF JOIN)

  • 하나의 테이블이 자기 자신과 조인하는 방식.
  • 테이블 내에 계층적인 관계(예: 사원-관리자, 부모-자식 카테고리)가 있을 때 사용함.
  • 반드시 테이블 별칭(Alias)을 사용하여 동일한 테이블을 논리적으로 다른 두 테이블처럼 구분해야 함.
/*
 * -- SELF JOIN 예시: 사원과 관리자 이름 조회 --
 * User 테이블을 직원(e)과 관리자(m)로 별칭을 부여하여 조인.
 * 직원의 manager_id와 관리자의 user_id를 연결고리로 사용함.
 * 매니저가 없는 최상위 직원은 INNER JOIN 시 조회되지 않으므로,
 * 모든 직원을 보고 싶다면 LEFT JOIN을 사용해야 함.
 */
SELECT
    e.name AS employee_name,
    m.name AS manager_name
FROM
    User e
LEFT JOIN User m ON e.manager_id = m.user_id;

4.2 NATURAL JOINUSING

  • 조인하는 두 테이블에 이름이 동일한 컬럼이 있을 때 ON 절을 간소화하는 방법.
    • NATURAL JOIN: 이름이 같은 모든 컬럼을 자동으로 조인 조건으로 사용함. 의도치 않은 컬럼이 포함될 위험이 있어 사용 시 주의가 필요함.
    • USING(컬럼명): 이름이 같은 여러 컬럼 중 조인에 사용할 공통 컬럼을 명시하여 NATURAL JOIN보다 안전함.

※ 실전 팁 (SQLD 핵심 포인트): NATURAL JOIN이나 USING 절에서 조인 기준으로 사용된 공통 컬럼SELECT 절에서 테이블 별칭을 붙일 수 없음. (예: SELECT u.user_id 불가, SELECT user_id 가능)

-- USING 절을 사용한 조인
SELECT
    user_id, -- 별칭 사용 불가
    u.name,  -- 나머지 컬럼은 별칭 사용 권장
    p.bio
FROM
    User u
INNER JOIN Profile p USING(user_id);

5. DBMS별 문법 차이

구분ANSI 표준 문법Oracle 구문법
INNER JOINFROM T1 INNER JOIN T2 ON T1.c1 = T2.c2FROM T1, T2 WHERE T1.c1 = T2.c2
LEFT OUTER JOINFROM T1 LEFT JOIN T2 ON T1.c1 = T2.c2FROM T1, T2 WHERE T1.c1 = T2.c2 (+)
RIGHT OUTER JOINFROM T1 RIGHT JOIN T2 ON T1.c1 = T2.c2FROM T1, T2 WHERE T1.c1 (+) = T2.c2
  • Oracle 구문법의 (+) 기호: 데이터가 부족하여 NULL이 표시될 수 있는 비기준 테이블 쪽의 조건 컬럼 뒤에 붙임.
  • 권장사항: ANSI 표준 문법은 가독성이 높고 DBMS 간 호환성이 좋으므로, 표준 문법 사용을 권장함. SQLD 시험에서도 표준 문법을 기준으로 출제됨.

6. 시험 문제 유형 및 함정 포인트

  • 조인 조건 누락: FROM 절에 여러 테이블을 나열하고 WHERE 절에 조인 조건을 빠뜨리면 카티션 곱이 발생한다는 점을 이용한 문제가 출제됨.
  • INNER JOIN vs OUTER JOIN: 게시물을 작성하지 않은 회원, 주문 이력이 없는 고객 등 특정 조건에 맞는 데이터가 없는 경우, 두 조인의 결과 행 수가 어떻게 달라지는지 묻는 문제가 단골로 출제됨.
  • USING 절의 별칭 문제: USING(column)으로 지정된 컬럼을 SELECT 절에서 table_alias.column 형태로 참조하면 오류가 발생한다는 점은 SQLD의 주요 함정 포인트임.
  • SELF JOIN의 개념: 하나의 테이블로 직원과 관리자 정보를 동시에 조회하는 등 SELF JOIN의 개념과 활용 사례를 묻는 문제가 출제될 수 있음.
  • Oracle 구문법: (+) 기호의 위치가 LEFT JOIN인지 RIGHT JOIN인지를 판단하는 문제가 나올 수 있음. (+)데이터가 없는 쪽에 붙는다는 것을 기억해야 함.
profile
Hello world!

0개의 댓글