SQL JOIN과 서브쿼리 - 테이블 결합과 중첩 질의
요약
SQL JOIN(INNER, CROSS, LEFT/RIGHT/FULL OUTER, 자연 조인)과 서브쿼리(IN, ALL, ANY)를 정보처리기사 실기 기출문제와 함께 학습합니다.
JOIN 핵심 정리
JOIN은 두 개 이상의 테이블1을 공통 컬럼2을 기준으로 결합하는 연산입니다. 공통 컬럼이란 두 테이블 모두에 존재하는 같은 의미의 컬럼(예: 사원번호)을 말합니다.
| JOIN 종류 | 설명 |
|---|---|
| INNER JOIN (동등 조인) | 두 테이블에서 조건이 일치하는 행만 반환 |
| CROSS JOIN | 두 테이블의 모든 조합 반환 (카티션 곱3) |
| LEFT OUTER JOIN | 왼쪽 테이블의 모든 행 + 오른쪽에서 일치하는 행 |
| RIGHT OUTER JOIN | 오른쪽 테이블의 모든 행 + 왼쪽에서 일치하는 행 |
| FULL OUTER JOIN | 양쪽 테이블의 모든 행 반환 |
| NATURAL JOIN (자연 조인) | 동등 조인에서 중복 컬럼 제거 |
INNER JOIN - 내부 조인
두 테이블에서 조건이 일치하는 행만 결합하여 반환합니다. 정보처리기사 실기에서 가장 자주 출제되는 조인 유형입니다.
JOIN ... ON 구문
테이블명.컬럼명은 "어느 테이블의 컬럼인지"를 명시하는 점 표기법4입니다. 두 테이블에 이름이 같은 컬럼이 있을 때 어느 테이블 것인지 구분하기 위해 사용합니다.
JOIN 대신 INNER JOIN이라고 써도 같은 의미입니다.
WHERE 구문 (동등 조인)
예시:
CROSS JOIN - 교차 조인
두 테이블의 모든 가능한 조합을 생성합니다. A 테이블이 3행, B 테이블이 2행이면 결과는 3 x 2 = 6행입니다.
예시:
A 테이블 (3행):
| NO | NAME |
|---|---|
| 1 | SMITH |
| 2 | ALLEN |
| 3 | SCOTT |
B 테이블 (2행):
| RNO | RULE |
|---|---|
| 1 | S% |
| 2 | %T% |
CROSS JOIN 결과 (3 x 2 = 6행):
| A.NAME | B.RULE |
|---|---|
| SMITH | S% |
| SMITH | %T% |
| ALLEN | S% |
| ALLEN | %T% |
| SCOTT | S% |
| SCOTT | %T% |
여기에 WHERE A.NAME LIKE B.RULE 조건을 추가하면, 각 조합에서 조건을 만족하는 행만 남습니다. LIKE와 % 패턴 매칭은 sql-select 페이지를 참고하세요.
CROSS JOIN + WHERE LIKE 결과:
| A.NAME | B.RULE | NAME LIKE RULE | 포함 여부 |
|---|---|---|---|
| SMITH | S% | S로 시작? YES | 포함 |
| SMITH | %T% | T 포함? YES | 포함 |
| ALLEN | S% | S로 시작? NO | 제외 |
| ALLEN | %T% | T 포함? NO | 제외 |
| SCOTT | S% | S로 시작? YES | 포함 |
| SCOTT | %T% | T 포함? YES | 포함 |
최종 결과: SMITH/S%, SMITH/%T%, SCOTT/S%, SCOTT/%T% (4행)
OUTER JOIN - 외부 조인
한쪽 테이블의 모든 행을 포함하고, 반대쪽에 일치하는 행이 없으면 NULL5로 채웁니다.
예시 테이블:
사원 테이블:
| 사원번호 | 이름 |
|---|---|
| 1 | 김감자 |
| 2 | 이고구마 |
| 3 | 박옥수수 |
부서 테이블:
| 사원번호 | 부서명 |
|---|---|
| 1 | 개발팀 |
| 2 | 디자인팀 |
(박옥수수는 아직 부서가 없습니다.)
LEFT OUTER JOIN
왼쪽 테이블(사원)의 모든 행을 포함합니다. 오른쪽에 일치하는 값이 없으면 NULL이 됩니다.
LEFT OUTER JOIN 결과:
| 사원.사원번호 | 이름 | 부서.사원번호 | 부서명 |
|---|---|---|---|
| 1 | 김감자 | 1 | 개발팀 |
| 2 | 이고구마 | 2 | 디자인팀 |
| 3 | 박옥수수 | NULL | NULL |
박옥수수는 부서 테이블에 대응하는 행이 없으므로 오른쪽 컬럼이 NULL로 채워집니다.
RIGHT OUTER JOIN
오른쪽 테이블(테이블2)의 모든 행을 포함합니다. 왼쪽에 일치하는 값이 없으면 NULL이 됩니다.
FULL OUTER JOIN
양쪽 테이블의 모든 행을 포함합니다. 어느 쪽에도 일치하지 않는 부분은 NULL로 채웁니다.
조인의 학술적 분류
| 조인 종류 | 설명 |
|---|---|
| 세타 조인 (Theta Join) | 모든 비교 연산자(=, >, <, >=, <=, !=)를 사용하는 조인. '세타(θ)'는 비교 연산자를 나타내는 수학 기호6 |
| 동등 조인 (Equi Join) | 세타 조인 중 등호(=)만 사용하는 조인 |
| 자연 조인 (Natural Join) | 동등 조인에서 중복 컬럼을 제거한 조인 |
세타 조인 ⊃ 동등 조인 ⊃ 자연 조인 순서로 범위가 좁아집니다. (⊃는 "포함한다"는 집합 기호로, 세타 조인이 가장 넓고 자연 조인이 가장 좁은 개념입니다.)
SQL 예시:
자연 조인의 중복 컬럼 제거:
동등 조인 결과 (부서번호 컬럼이 두 번 나타남):
| 사원.부서번호 | 이름 | 부서.부서번호 | 부서명 |
|---|---|---|---|
| 10 | 김감자 | 10 | 개발팀 |
자연 조인 결과 (중복 컬럼 제거 후):
| 부서번호 | 이름 | 부서명 |
|---|---|---|
| 10 | 김감자 | 개발팀 |
서브쿼리 (Subquery)
다른 SQL문 안에 포함된 SELECT문을 서브쿼리라고 합니다. 먼저 안쪽 서브쿼리가 실행되어 결과를 만들고, 그 결과를 바깥 쿼리에서 사용합니다.
WHERE ... IN (서브쿼리)
서브쿼리의 결과 목록에 포함되는 행만 조회합니다.
예시:
중첩 서브쿼리 해석 순서
서브쿼리가 여러 겹으로 중첩된 경우, 가장 안쪽 서브쿼리부터 바깥쪽으로 순서대로 해석합니다.
풀이 순서: ① → ② → ③
ALL / ANY 연산자
서브쿼리 결과의 모든 값 또는 하나 이상의 값과 비교합니다.
| 연산자 | 의미 |
|---|---|
| ALL | 서브쿼리의 모든 값과 비교 (모두 만족해야 참) |
| ANY (= SOME) | 서브쿼리의 하나라도 만족하면 참 |
ALL 단계별 풀이:
① 서브쿼리 실행: SELECT 무게 FROM 감자 WHERE 농장 = 'A' → 결과: (100, 150)
② 무게 > ALL (100, 150) = 무게 > 100 AND 무게 > 150 = 무게 > 150 (모든 값보다 커야 하므로 가장 큰 값인 150보다 커야 함)
③ 무게가 150보다 큰 감자만 최종 결과에 포함
ANY 예시:
A농장 감자 무게가 100, 150이면, 무게 > ANY (100, 150) = 무게 > 100 OR 무게 > 150 = 무게 > 100 (하나라도 만족하면 되므로 가장 작은 값인 100보다 크면 됨)
정보처리기사 실기 대비 문제
Footnotes
-
테이블(Table)은 데이터를 행(가로 줄)과 열(세로 줄)로 구성한 2차원 구조입니다. 엑셀 시트와 같이 생겼으며, 데이터베이스에서 데이터를 저장하는 기본 단위입니다. ↩
-
컬럼(Column)은 테이블의 세로 줄 하나로, 같은 종류의 데이터를 담습니다. 예를 들어 사원 테이블에서 '사원번호' 열 전체가 하나의 컬럼입니다. ↩
-
카티션 곱(Cartesian Product)은 두 집합의 모든 원소 쌍을 조합하는 수학 연산입니다. A가 3개, B가 2개 원소를 가지면 결과는 3 x 2 = 6개입니다. ↩
-
점 표기법(Dot Notation):
테이블명.컬럼명형식으로 어느 테이블의 컬럼인지 명확히 지정합니다. 예:사원.사원번호는 사원 테이블의 사원번호 컬럼을 의미합니다. ↩ -
NULL은 "값이 없음"을 나타내는 특수 표시입니다. 0이나 빈 문자열('')과 다르게, 해당 데이터 자체가 존재하지 않음을 의미합니다. ↩
-
관계 대수(Relational Algebra)에서 비교 연산자를 θ(세타)로 표기하는 관례에서 이름이 유래했습니다. θ는
=,≠,>,<,≥,≤중 어떤 연산자든 될 수 있습니다. ↩