MSSQL JOIN관련 예제

MSSQL JOIN 완벽 가이드 핵심 예제부터 성능 최적화



관계형 데이터베이스의 핵심은 바로 '관계'입니다. 서로 다른 테이블에 흩어진 데이터를 의미 있게 연결하고 분석하는 능력은 모든 IT 전문가에게 필수적인데요. 그 중심에 MSSQL JOIN이 있습니다. 이 글에서는 MSSQL JOIN의 핵심 개념부터 다양한 유형별 예제, 도입 효과, 그리고 미래 기술과의 연관성까지 깊이 있게 분석하여 여러분의 데이터 활용 능력을 한 단계 높여드립니다.

핵심 개념: 데이터 연결의 마법

MSSQL JOIN은 두 개 이상의 테이블에서 관련 있는 행(Row)들을 결합하여 새로운 결과 집합을 만드는 데 사용되는 SQL 문법입니다. 관계형 데이터베이스는 데이터의 중복을 줄이고 무결성을 유지하기 위해 데이터를 여러 테이블로 분리하여 저장하는 정규화 과정을 거칩니다. 이때 분리된 데이터들을 다시 하나로 합쳐서 원하는 정보를 얻기 위해 JOIN이 필수적으로 사용됩니다.

예를 들어, 직원 테이블과 부서 테이블이 있다고 가정해 봅시다. 직원의 이름과 그 직원이 속한 부서의 이름을 함께 보고 싶다면, DeptID와 같은 공통 컬럼을 기준으로 두 테이블을 연결(JOIN)해야 합니다.

MSSQL JOIN 유형별 핵심 예제와 설명

효과적인 JOIN 사용을 위해, 먼저 예제에 사용될 가상의 테이블을 정의하겠습니다.

-- 예제 테이블 생성 및 데이터 삽입 (가정)
CREATE TABLE Departments (
DeptID INT PRIMARY KEY,
DeptName NVARCHAR(50)
);
INSERT INTO Departments VALUES (1, 'HR'), (2, 'Development'), (3, 'Sales'), (4, 'Marketing');

CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName NVARCHAR(50),
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
);
INSERT INTO Employees VALUES (101, '김철수', 1), (102, '박영희', 2), (103, '이민수', 1), (104, '최지영', NULL); -- NULL은 부서 미지정 직원을 가정
INSERT INTO Employees VALUES (105, '정수진', 3);

1. INNER JOIN: 교집합 찾기

INNER JOIN은 두 테이블에서 JOIN 조건에 맞는 모든 행을 반환합니다. 즉, 양쪽 테이블 모두에 존재하는 데이터만을 가져옵니다.

예제: 모든 직원의 이름과 그들이 속한 부서의 이름을 조회
SELECT E.EmpName, D.DeptName
FROM Employees AS E
INNER JOIN Departments AS D
ON E.DeptID = D.DeptID;

결과 예상: DeptIDNULL최지영은 결과에 포함되지 않습니다. 또한, Employees 테이블에 속한 직원이 없는 Marketing 부서도 결과에 나타나지 않습니다.

2. LEFT JOIN (LEFT OUTER JOIN): 왼쪽 기준 전체 포함

LEFT JOIN은 왼쪽 테이블(FROM 절에 먼저 오는 테이블)의 모든 행을 포함하고, 오른쪽 테이블에서는 JOIN 조건에 맞는 행만 가져옵니다. 만약 오른쪽 테이블에 일치하는 행이 없으면, 해당 컬럼은 `NULL`로 표시됩니다.

예제: 모든 직원의 이름과 그들이 속한 부서의 이름을 조회하되, 부서가 없는 직원도 포함
SELECT E.EmpName, D.DeptName
FROM Employees AS E
LEFT JOIN Departments AS D
ON E.DeptID = D.DeptID;

결과 예상: 최지영과 같이 DeptIDNULL인 직원도 모두 포함되며, DeptNameNULL로 표시됩니다.

3. RIGHT JOIN (RIGHT OUTER JOIN): 오른쪽 기준 전체 포함

RIGHT JOIN은 LEFT JOIN과 반대로, 오른쪽 테이블의 모든 행을 포함하고, 왼쪽 테이블에서는 JOIN 조건에 맞는 행만 가져옵니다. 일치하는 행이 없으면 왼쪽 테이블의 컬럼은 NULL로 표시됩니다.

예제: 모든 부서의 이름과 그 부서에 속한 직원의 이름을 조회하되, 직원이 없는 부서도 포함
SELECT D.DeptName, E.EmpName
FROM Employees AS E
RIGHT JOIN Departments AS D
ON E.DeptID = D.DeptID;

결과 예상: Marketing 부서와 같이 속한 직원이 없는 부서도 모두 포함되며, EmpNameNULL로 표시됩니다.

4. FULL JOIN (FULL OUTER JOIN): 양쪽 모두 포함

FULL JOIN은 두 테이블의 모든 행을 포함합니다. JOIN 조건에 일치하는 행이 있으면 해당 데이터를, 일치하는 행이 없으면 NULL을 표시합니다. 이는 LEFT JOIN과 RIGHT JOIN의 결과를 합친 것과 같습니다.

예제: 모든 직원과 모든 부서의 정보를 연결하여 조회
SELECT E.EmpName, D.DeptName
FROM Employees AS E
FULL JOIN Departments AS D
ON E.DeptID = D.DeptID;

결과 예상: 최지영(부서 없음)과 Marketing(직원 없음) 모두 포함되며, 일치하지 않는 부분은 NULL로 표시됩니다.

5. CROSS JOIN: 모든 조합 생성 (주의 필요!)

CROSS JOIN은 두 테이블의 모든 행에 대해 가능한 모든 조합을 생성합니다. 이는 JOIN 조건 없이 두 테이블을 곱한 결과와 같으며, 데이터의 양이 기하급수적으로 늘어나므로 신중하게 사용해야 합니다.

예제: 모든 직원을 모든 부서에 임시로 매칭하는 경우
SELECT E.EmpName, D.DeptName
FROM Employees AS E
CROSS JOIN Departments AS D;

결과 예상: 직원 수 * 부서 수 만큼의 행이 반환됩니다. (5 * 4 = 20개 행)

6. SELF JOIN: 같은 테이블 내 관계 분석

SELF JOIN은 하나의 테이블을 두 번 사용하여 자체적으로 JOIN하는 방식입니다. 주로 계층 구조 데이터(예: 직원-관리자 관계)나 동일 테이블 내의 관련 데이터를 분석할 때 유용합니다. 반드시 테이블에 별칭(Alias)을 지정해야 합니다.

예제: (추가 테이블 가정) 직원의 관리자 정보 조회 (Self-JOIN 예시를 위해 Managers 테이블 추가 가정)
-- Self JOIN 예시를 위한 Employees 테이블 구조 변경 또는 추가 테이블 가정
-- (예시 편의상 기존 Employees 테이블에 ManagerID 컬럼 추가 가정)
ALTER TABLE Employees ADD ManagerID INT;
UPDATE Employees SET ManagerID = 101 WHERE EmpID = 102; -- 김철수가 박영희의 관리자
UPDATE Employees SET ManagerID = 101 WHERE EmpID = 103; -- 김철수가 이민수의 관리자
UPDATE Employees SET ManagerID = 105 WHERE EmpID = 104; -- 정수진이 최지영의 관리자 (null 직원에 관리자 부여)

SELECT E.EmpName AS Employee, M.EmpName AS Manager
FROM Employees AS E
LEFT JOIN Employees AS M
ON E.ManagerID = M.EmpID;

결과 예상: 각 직원과 그들의 관리자 이름을 연결하여 보여줍니다. 관리자가 없는 직원은 Manager 컬럼이 NULL로 표시됩니다.


Q. JOIN 사용 시 성능을 최적화하려면 어떻게 해야 하나요?

① JOIN 조건 컬럼에 인덱스(Index)를 적절히 생성하고 활용하는 것 
② 데이터 양을 최소화하기 위해 JOIN 전에 필터링(WHERE 절)을 먼저 적용하는 것 
③ 테이블의 특성과 쿼리 목적에 맞는 적절한 JOIN 유형을 선택하는 것 
통계(Statistics)를 최신 상태로 유지하여 쿼리 옵티마이저가 최적의 실행 계획을 세우도록 돕는 것 등이 있습니다.

본 매거진은 IT Archive Lab의 구글 Gemini API 에이전트를 통해 자동 빌드되었습니다.

Comment

다음 이전