글 목록

최신 글과 검색 결과
DEVELOPMENT

SQL JOIN문법, 데이터베이스(DB) 테이블 결합의 모든 것

간지뽕빨리턴님

이 글의 목차

    반응형

    SQL JOIN 종류(INNER · LEFT · RIGHT · FULL OUTER)의 개념 차이를 예제로 정리합니다.

    헷갈리는 SQL JOIN, 한 번에 정리해 봅시다

    관계형 데이터베이스에서는 정보가 여러 테이블로 정규화되어 나뉘어 저장됩니다. 예를 들어 직원 정보와 부서 정보를 별도 테이블에 분리해 두는 경우, 필요한 데이터를 한 곳에서 조회하려면 테이블을 조인해야 합니다. JOIN은 데이터베이스 내 여러 테이블의 레코드를 조합하여 하나의 결과 집합으로 표현해 주는 SQL 구문으로, 두 테이블 간 공통 필드의 값을 기준으로 행들을 연결합니다. 이를 통해 마치 하나의 테이블에 있던 것처럼 데이터를 결합하여 활용할 수 있습니다.

    SQL 표준에는 여러 JOIN이 있지만, 실무에서 주로 사용하는 것은 INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN 네 가지입니다. 각 JOIN은 포함하는 데이터 범위에 차이가 있으므로, 용도에 맞게 올바른 JOIN을 선택하는 것이 중요합니다. 이 글에서는 직원·부서 테이블 예제로 네 가지 JOIN의 차이를 결과까지 비교하며 정리합니다.

    목차

      SQL JOIN 예제 준비

      예시 테이블 생성

      -- 직원 테이블 생성
      CREATE TABLE Employee (
          EmpID INT PRIMARY KEY,
          EmpName VARCHAR(50),
          BirthYear INT,
          DeptID INT
      );
      
      -- 부서 테이블 생성
      CREATE TABLE Department (
          DeptID INT PRIMARY KEY,
          DeptName VARCHAR(50)
      );
      
      -- 직원 데이터 입력
      INSERT INTO Employee (EmpID, EmpName, BirthYear, DeptID) VALUES
      (1, '최영환', 1994, 30),
      (2, '홍길동', 1950, 20),
      (3, '신형만', 1983, 15);
      
      -- 부서 데이터 입력
      INSERT INTO Department (DeptID, DeptName) VALUES
      (30, '솔루션개발'),
      (20, '경영지원'),
      (15, 'DX사업부'),
      (40, '스마트팩토리'); -- 직원 없는 부서

      두 테이블을 잇는 공통 키는 DeptID입니다. 직원 3명은 모두 부서가 있고, 부서 4개 중 '스마트팩토리(40)'에는 소속 직원이 없습니다. 이 비대칭 덕분에 JOIN 종류에 따라 결과가 어떻게 달라지는지 명확히 비교할 수 있습니다.

      INNER JOIN (내부 조인) — 교집합 조회

      INNER JOIN은 두 테이블에서 공통으로 일치하는 레코드만 결합하여 반환합니다. 조건에 양쪽 모두 존재하는 데이터만 결과에 포함되므로, 어느 한쪽에만 존재하는 데이터는 빠집니다. 일반적으로 JOIN 키워드만 사용하면 기본적으로 INNER JOIN으로 동작하며, 가장 흔히 쓰이는 조인 방식입니다.

      직원(Employee) 테이블과 부서(Department) 테이블을 Employee.DeptIDDepartment.DeptID를 기준으로 INNER JOIN 하면, 부서가 할당된 직원들만 조회됩니다. 부서가 없는 직원이나, 직원이 한 명도 없는 부서는 결과에서 제외됩니다. 즉 양쪽 모두에 존재하는 교집합 데이터만 얻습니다.

      예시 쿼리

      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e
      INNER JOIN Department d
          ON e.DeptID = d.DeptID;

      결과

      EmpName BirthYear DeptName
      최영환 1994 솔루션개발
      홍길동 1950 경영지원
      신형만 1983 DX사업부

      직원 3명이 모두 실제 부서와 연결되므로 전부 표시되고, 직원이 없는 '스마트팩토리'는 제외됩니다.

      LEFT JOIN (좌측 조인) — 왼쪽 테이블 모두 포함

      LEFT JOIN은 왼쪽 테이블의 모든 행을 결과에 유지하면서, 오른쪽 테이블에서 일치하는 행을 결합합니다. 오른쪽에 대응되는 값이 없으면 해당 칼럼은 NULL로 채워진 채 결과에 포함됩니다.

      직원(Employee)을 왼쪽에 두고 부서(Department)와 LEFT JOIN 하면 모든 직원이 결과에 나타납니다. 부서가 있는 직원은 부서명이 표시되고, 부서가 없는 직원도 결과에 나오되 부서명이 NULL로 표시됩니다. 반대로 직원이 없는 부서는 결과에 나타나지 않습니다.

      LEFT JOIN은 주요 데이터 세트(왼쪽)의 손실 없이 부가 정보를 합칠 때 많이 사용됩니다. 또한 WHERE d.DeptID IS NULL 조건을 더하면 "왼쪽에는 있지만 오른쪽에는 없는 데이터"를 쉽게 찾을 수 있습니다.

      예시 쿼리

      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e
      LEFT JOIN Department d
          ON e.DeptID = d.DeptID;

      결과

      EmpName BirthYear DeptName
      최영환 1994 솔루션개발
      홍길동 1950 경영지원
      신형만 1983 DX사업부

      현재 데이터에서는 모든 직원이 부서와 매칭되므로 INNER JOIN과 결과가 같습니다. 만약 부서 없는 직원이 있었다면 그 직원도 표시되며 DeptName이 NULL로 나옵니다.

      RIGHT JOIN (우측 조인) — 오른쪽 테이블 모두 포함

      RIGHT JOIN은 LEFT JOIN과 반대로 오른쪽 테이블의 모든 행을 유지하면서, 왼쪽 테이블에서 일치하는 행을 결합합니다. 왼쪽에 대응되는 값이 없으면 NULL로 표시됩니다.

      부서(Department)를 오른쪽에 두고 직원(Employee)과 RIGHT JOIN 하면 모든 부서가 결과에 나타납니다. 직원이 없는 부서는 부서명이 표시되지만 직원 칼럼은 NULL로 나타납니다. 반대로 부서가 없는 직원은 결과에서 제외됩니다.

      RIGHT JOIN은 LEFT JOIN과 기능이 대칭적이지만, 대부분의 경우 테이블 순서를 바꿔 LEFT JOIN으로 같은 결과를 얻을 수 있어 실무에서는 자주 쓰이지 않습니다.

      예시 쿼리

      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e
      RIGHT JOIN Department d
          ON e.DeptID = d.DeptID;

      결과

      EmpName BirthYear DeptName
      최영환 1994 솔루션개발
      홍길동 1950 경영지원
      신형만 1983 DX사업부
      NULL NULL 스마트팩토리

      모든 부서가 표시되고, 직원이 없는 '스마트팩토리'는 EmpName·BirthYear가 NULL로 나옵니다.

      FULL OUTER JOIN (풀 아우터 조인) — 전체 합집합 조회

      FULL OUTER JOIN은 왼쪽과 오른쪽 테이블의 모든 행을 포함하여 결합하는 방식입니다. 교집합뿐 아니라 한쪽에만 존재하는 데이터까지 모두 합쳐 보여줍니다.

      직원(Employee)과 부서(Department)를 FULL OUTER JOIN 하면 모든 직원과 모든 부서가 결과에 포함됩니다. 부서가 없는 직원은 부서 칼럼이 NULL로, 직원이 없는 부서는 직원 칼럼이 NULL로 표시됩니다.

      단, 일부 DBMS(MySQL 8.0 등)는 FULL OUTER JOIN을 지원하지 않습니다. 이 경우 LEFT JOIN 결과와 RIGHT JOIN 결과를 UNION으로 합쳐 동일한 효과를 낼 수 있습니다.

      예시 쿼리

      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e
      FULL OUTER JOIN Department d
          ON e.DeptID = d.DeptID;
      
      -- MySQL 등 FULL OUTER JOIN 미지원 DBMS에서는 아래처럼 우회
      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e LEFT JOIN Department d ON e.DeptID = d.DeptID
      UNION
      SELECT e.EmpName, e.BirthYear, d.DeptName
      FROM Employee e RIGHT JOIN Department d ON e.DeptID = d.DeptID;

      결과

      EmpName BirthYear DeptName
      최영환 1994 솔루션개발
      홍길동 1950 경영지원
      신형만 1983 DX사업부
      NULL NULL 스마트팩토리

      직원 3명과 부서 4개가 모두 표시됩니다. '스마트팩토리'는 직원이 없어 직원 칼럼이 NULL이고, 만약 부서 없는 직원이 추가되면 그 직원은 DeptName이 NULL로 나옵니다.

      JOIN 종류 한눈에 비교

      JOIN 의미 포함 범위 예제 결과 행 수
      INNER JOIN 교집합 양쪽 모두 존재하는 행만 3행
      LEFT JOIN 왼쪽 기준 왼쪽 전부 + 일치하는 오른쪽 3행
      RIGHT JOIN 오른쪽 기준 오른쪽 전부 + 일치하는 왼쪽 4행
      FULL OUTER JOIN 합집합 양쪽 모든 행 4행

      마무리

      네 가지 JOIN을 요약하면 다음과 같습니다.

      INNER JOIN — 교집합. 양쪽에 모두 존재하는 데이터만 조회.

      LEFT JOIN — 왼쪽 기준. 왼쪽 데이터는 모두 유지, 오른쪽에 없는 값은 NULL.

      RIGHT JOIN — 오른쪽 기준. 오른쪽 데이터는 모두 유지, 왼쪽에 없는 값은 NULL.

      FULL OUTER JOIN — 합집합. 양쪽 모든 데이터를 다 보여줌.

      추가 팁

      조인 칼럼에 인덱스를 걸면 성능이 크게 향상됩니다. 또한 너무 많은 테이블을 한 번에 조인하면 쿼리가 복잡해지고 성능 저하가 발생할 수 있으므로, 필요하면 뷰나 서브쿼리로 나누는 것이 좋습니다.

      JOIN의 기본 원리를 이해하면 원하는 데이터를 빠뜨리지 않고 정확하게 조회할 수 있습니다. 상황에 맞는 JOIN을 선택하여 효율적인 데이터 결합을 해보세요.