1) 조인 기본 종류 요약
| 조인 종류 | 설명 | 예제 | 실무 활용 |
|---|---|---|---|
| INNER JOIN | 양쪽 테이블에서 조건 일치 행만 반환한다. |
|
정확한 관계가 있을 때 기본으로 사용한다. |
| LEFT OUTER JOIN | 왼쪽 테이블은 모두, 오른쪽은 매칭될 때만 반환한다. |
|
누락 데이터가 있어도 왼쪽 기준으로 모두 조회한다. |
| RIGHT OUTER JOIN | 오른쪽 테이블은 모두, 왼쪽은 매칭될 때만 반환한다. |
|
마스터(오른쪽) 기준 전체 목록에 매핑 상태를 보고 싶을 때 쓴다. |
| FULL OUTER JOIN | 양쪽 전체를 합쳐 보여주며, 매칭 안 되는 컬럼은 NULL이다. |
|
양쪽 누락을 함께 파악한다. |
| NATURAL JOIN | 동명이 컬럼으로 자동 조인한다. 조건을 직접 쓰지 않는다. |
|
의도치 않은 컬럼이 엮일 수 있어 권장하지 않는다. |
| SELF JOIN | 자기 자신과 조인한다. |
|
상하 관계, 부모-자식 구조 조회에 사용한다. |
| CROSS JOIN | 곱집합을 반환한다. |
|
테스트나 조합 생성에 드물게 사용한다. |
2) 실무에서 자주 쓰는 기본 패턴
2-1. 직원과 부서 함께 조회 (INNER JOIN)
SELECT e.employee_id, e.first_name, d.department_name
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id;
2-2. 부서 미배정 직원도 포함 (LEFT JOIN)
SELECT e.employee_id, e.first_name, d.department_name
FROM employees e
LEFT JOIN departments d
ON e.department_id = d.department_id;
2-3. 자기 자신과 조인 (SELF JOIN, 직원 ↔ 매니저)
SELECT e.employee_id,
e.first_name AS employee,
m.first_name AS manager
FROM employees e
JOIN employees m
ON e.manager_id = m.employee_id;
3) 조인 + 집계/윈도우/서브쿼리 조합
3-1. 부서별 인원 수 (LEFT JOIN + GROUP BY + HAVING)
직원이 5명 이상인 부서만 조회한다.
SELECT d.department_name,
COUNT(e.employee_id) AS emp_count
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
GROUP BY d.department_name
HAVING COUNT(e.employee_id) >= 5;
3-2. 부서별 급여 합을 행에 함께 표기 (PARTITION BY)
SELECT e.department_id,
e.first_name,
e.salary,
SUM(e.salary) OVER (PARTITION BY e.department_id) AS dept_total
FROM employees e;
3-3. 부서별 급여 순위 (RANK + PARTITION BY)
SELECT e.first_name,
e.department_id,
e.salary,
RANK() OVER (PARTITION BY e.department_id ORDER BY e.salary DESC) AS sal_rank
FROM employees e;
3-4. 부서별 연봉 상위 3명 (윈도우 순위 필터)
SELECT *
FROM (
SELECT e.*,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees e
)
WHERE rnk <= 3;
3-5. WITH로 평균 급여 구해 조인 (WITH + JOIN + 조건)
WITH dept_avg AS (
SELECT department_id, AVG(salary) AS avg_sal
FROM employees
GROUP BY department_id
)
SELECT e.first_name,
e.salary,
d.avg_sal
FROM employees e
JOIN dept_avg d
ON e.department_id = d.department_id
WHERE e.salary >= d.avg_sal;
3-6. 3테이블 조인 (직원 + 부서 + 지역)
SELECT e.first_name,
d.department_name,
l.city
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id;
4) 페이징과 조인 결합 (ROWNUM 패턴)
Oracle 11g에서 페이징은 인라인 뷰 + ROWNUM을 사용한다.
SELECT *
FROM (
SELECT x.*, ROWNUM rn
FROM (
SELECT e.employee_id, e.first_name, d.department_name, e.hire_date
FROM employees e
JOIN departments d ON e.department_id = d.department_id
ORDER BY e.hire_date DESC
) x
WHERE ROWNUM <= :offset + :limit
)
WHERE rn > :offset;
- INNER vs LEFT: 기준 테이블을 명확히 한다. 기준을 잃으면 건수가 틀어진다.
- FULL OUTER JOIN은 전체 누락 파악에 유용하나 비용이 클 수 있다.
- NATURAL JOIN은 컬럼명 의존도가 높아 유지보수에 취약하다. 가급적 지양한다.
- 조인 후 집계 시 GROUP BY 컬럼을 정확히 지정한다. 의도치 않은 중복행을 경계한다.
- 11g 페이징은 인라인 뷰 + ROWNUM을 사용한다. ORDER BY는 반드시 가장 안쪽에서 먼저 수행한다.
- 성능 이슈가 있으면 조인 컬럼의 인덱스, 조인 순서, 통계 최신화, 힌트 사용을 점검한다.
'DB' 카테고리의 다른 글
| Oracle SQL 테이블 설계부터 집계함수까지 (0) | 2025.06.05 |
|---|---|
| Oracle 인덱스 적용 전·후 성능 비교 (0) | 2025.06.05 |
| Oracle 데이터 타입 & 제약조건(Constraints) 정리 (0) | 2025.06.02 |
| Oracle SQL 예제 (0) | 2025.05.30 |
| MySQL vs Oracle 11g 데이터 타입 비교 (0) | 2025.05.30 |