같은 테이블의 행 비교하기
쌍과 관계를 찾습니다.
같은 테이블의 행 비교하기은(는) CoddyKit의 무료 SQL Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
자기 조인이란?
자기 조인은 테이블을 자기 자신과 조인하는 것입니다. 처음에는 낯설게 들릴 수 있지만, 같은 테이블 안의 행을 비교할 때 유용한 강력한 기법입니다.
employees 테이블에서 각 직원의 manager_id가 같은 테이블의 다른 행을 가리킨다고 생각해 보겠습니다. 자기 조인을 사용하면 하나의 쿼리에서 각 직원을 해당 관리자의 행과 연결할 수 있습니다.
예시 테이블 설정하기
이번 학습 전체에서 사용할 간단한 employees 테이블을 만들어 보겠습니다. 각 행에는 id, name, salary, 그리고 같은 테이블의 다른 직원을 참조하는 manager_id가 있습니다.
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
salary INT,
manager_id INT
);
INSERT INTO employees VALUES
(1, 'Alice', 90000, NULL),
(2, 'Bob', 70000, 1),
(3, 'Carol', 65000, 1),
(4, 'Dave', 55000, 2),
(5, 'Eve', 60000, 2),
(6, 'Frank', 48000, 3);기본 자기 조인 구문
자기 조인을 수행하려면 서로 다른 두 별칭을 사용하여 같은 테이블을 두 번 참조합니다. 별칭은 테이블을 서로 분리된 두 복사본처럼 사용할 수 있게 합니다. 그런 다음 두 복사본을 연결하는 조인 조건을 지정합니다.
여기서는 employees에 e(직원)라는 별칭을 지정하고, m(관리자)과 연결한 다음 e.manager_id = m.id를 기준으로 일치시킵니다.
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;LEFT JOIN으로 최상위 행 포함하기
일반적인 INNER JOIN은 manager_id가 NULL인 행을 제거하므로 최상위 직원인 Alice(CEO)가 결과에서 제외됩니다.
LEFT JOIN을 사용하면 관리자가 없는 직원을 포함하여 모든 직원이 표시됩니다. 이러한 직원의 관리자 열에는 단순히 NULL이 표시됩니다.
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
ORDER BY m.name NULLS LAST, e.name;속성을 공유하는 쌍 찾기
자기 조인은 동일한 값을 공유하는 행 쌍을 찾을 때도 유용합니다. 예를 들어 같은 관리자에게 보고하는 모든 직원 쌍을 찾을 수 있습니다.
a.id < b.id 조건은 (Bob, Carol)과 (Carol, Bob)처럼 중복된 쌍이 모두 결과에 나타나는 것을 방지합니다.
SELECT
a.name AS employee_1,
b.name AS employee_2,
a.manager_id AS shared_manager
FROM employees a
JOIN employees b
ON a.manager_id = b.manager_id
AND a.id < b.id;행 간 급여 비교하기
자기 조인을 사용하여 행 간의 숫자 값을 비교할 수 있습니다. 아래 쿼리는 자신의 관리자 급여보다 높은 급여를 받는 모든 직원을 찾습니다. 이는 전형적인 분석 확인입니다.
SELECT
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;일치하는 대상이 없는 행 찾기
LEFT JOIN과 WHERE ... IS NULL 확인을 함께 사용하면 일치하는 상대 행이 없는 행을 찾을 수 있습니다. 여기서는 자신에게 보고하는 직원이 아무도 없는 직원, 즉 계층 구조의 말단 노드를 찾습니다.
SELECT e.name AS employee
FROM employees e
LEFT JOIN employees sub ON sub.manager_id = e.id
WHERE sub.id IS NULL
ORDER BY e.name;직속 부하 직원 수 세기
테이블을 자기 자신과 조인하고 관리자 쪽을 기준으로 그룹화하면 각 관리자에게 직속 부하 직원이 몇 명 있는지 계산할 수 있습니다. 부하 직원이 0명인 직원도 LEFT JOIN을 통해 포함됩니다.
SELECT
m.name AS manager,
COUNT(e.id) AS direct_reports
FROM employees m
LEFT JOIN employees e ON e.manager_id = m.id
GROUP BY m.id, m.name
ORDER BY direct_reports DESC;자기 조인을 명확하게 하기 위해 CTE 사용하기
자기 조인 쿼리가 복잡해지면 공통 테이블 식(CTE)으로 감싸 논리를 더 쉽게 읽을 수 있습니다. 계층 구조를 위한 CTE를 하나 정의한 다음 이를 명확하게 조회합니다.
WITH hierarchy AS (
SELECT
e.id AS emp_id,
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
)
SELECT *
FROM hierarchy
WHERE mgr_salary IS NOT NULL
AND emp_salary > mgr_salary;비계층적 테이블에서 자기 조인하기
자기 조인은 관리자-직원 계층 구조에만 사용할 수 있는 것은 아닙니다. 아래 예에서는 products 테이블을 사용하여 같은 카테고리에 속한 모든 제품 쌍을 찾습니다. 이는 추천 엔진이나 유사성 확인에 유용합니다.
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50),
category VARCHAR(30)
);
INSERT INTO products VALUES
(1, 'Laptop', 'Electronics'),
(2, 'Phone', 'Electronics'),
(3, 'Tablet', 'Electronics'),
(4, 'Shirt', 'Clothing'),
(5, 'Jeans', 'Clothing');
SELECT
a.name AS product_1,
b.name AS product_2,
a.category
FROM products a
JOIN products b
ON a.category = b.category
AND a.id < b.id;주의할 점: 카테시안 곱과 중복
자기 조인에서 흔히 발생하는 실수는 두 가지입니다. 조인 조건을 완전히 빠뜨리는 카테시안 곱과, a.id <> b.id를 a.id < b.id 대신 사용하여 생기는 중복된 쌍입니다.
항상 조인 조건이 올바른지 확인하고, 순서가 없는 쌍만 필요할 때는 <> 대신 <를 사용합니다.
-- Wrong: returns every ordered pair (A,B) AND (B,A)
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id <> b.id;
-- Correct: returns each unordered pair once
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id < b.id;빠른 확인
자기 조인과 동일한 테이블의 행 비교에 대한 이해도를 확인해 보십시오.
학습 내용 복습
이번 학습에서는 자기 조인을 사용하여 동일한 테이블 안의 행을 비교하는 방법을 배웠습니다.
핵심 내용:
- 테이블에 별칭을 두 번 지정하십시오(예:
e와m). 그러면 데이터베이스가 두 테이블을 서로 다른 데이터 원본으로 처리합니다. - 일치하는 행만 필요할 때는
INNER JOIN을 사용하고, 일치하지 않는 행도 포함하려면LEFT JOIN을 사용하십시오. - 순서가 없는 중복 쌍을 피하려면
a.id < b.id를 사용하십시오. - 자기 조인은 계층 구조(관리자/직원), 유사성 검색(같은 범주), 그리고 동일한 테이블의 두 행을 서로 연결해야 하는 모든 비교에 사용할 수 있습니다.
- CTE를 사용하면 복잡한 자기 조인 질의를 훨씬 쉽게 읽고 유지 관리할 수 있습니다.
자주 묻는 질문
“같은 테이블의 행 비교하기” 강의는 무료인가요?
네 — “같은 테이블의 행 비교하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Academy 강의 전체를 잠금 해제할 수 있습니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“같은 테이블의 행 비교하기”에서 뭘 배우나요?
쌍과 관계를 찾습니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“같은 테이블의 행 비교하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 셀프 JOIN이란 무엇인가요
- 직원과 관리자
- 같은 테이블의 행 비교하기
- 셀프 JOIN의 한계