본문 바로가기
오라클

[오라클] WITH절(Subquery Factoring) 완벽 정리

by devlog93 2026. 1. 10.

SQL을 작성하다 보면은 같은 서브쿼리를 여러 번 반복해서 사용해야 하는 경우가 자주 발생한다. 쿼리가 길어지고 가독성이 떨어지면서 수정이 필요할 때도 불편하다. 이럴 때 사용하는 것이 WITH절이다...! WITH절은 서브쿼리에 이름을 붙여서 미리 정의해두고 이후 메인 쿼리에서 테이블처럼 사용하는 문법이다. 오라클에서는 이것을 서브쿼리 팩토링이라고 한다.


1. WITH절 기본 개념

WITH절은 SELECT보다 먼저 실행되고 임시 결과 집합을 만든다.

WITH 서브쿼리명 AS (
	SELECT 컬럼
      FROM 테이블
     WHERE 조건
)
SELECT *
  FROM 서브쿼리명;

복잡한 서브쿼리를 한번 정의하고 재사용이 가능하다...!


2.  WITH절이 필요한 이유?

❌ WITH절 없이 서브쿼리 사용하게되면

SELECT EMPNO
     , ENAME
     , SAL
  FROM EMP
 WHERE DEPTNO IN (
                    SELECT DEPTNO
                      FROM EMP
                     WHERE SAL >= 3000
                    );

이런 서브쿼리가 반복되게 된다면???

  • SQL가독성이 떨어지고
  • 유지보수가 어려워지고
  • 실수 발생이 높아진다.

⭕ WITH절 사용하게 되면

WITH SALARY_DEPT AS (
	SELECT DEPTNO
      FROM EMP
     WHERE SAL >= 3000
)
SELECT EMPNO
     , ENAME
     , SAL
  FROM EMP
 WHERE DEPTNO IN (
                  SELECT DEPTNO
                    FROM SALARY_DEPT
                 );

✔️ 쿼리가 훨씬 읽기 쉬워지고 서브쿼리의 의미가 명확해짐...!!!


3. WITH절 여러 개 사용하기

WITH절은 콤마(,)로 여러 개 정의가 가능하다.

WITH DEPT_AVG AS (
	SELECT DEPTNO
         , AVG(SAL) AS AVG_SAL
      FROM EMP
     GROUP BY DEPTNO
),
PAID_EMP AS (
	SELECT EMPNO
         , ENAME
         , SAL
         , DEPTNO
      FROM EMP
     WHERE SAL >= 3000
)
SELECT A.EMPNO
     , A.ENAME
     , A.SAL
     , B.AVG_SAL
  FROM PAID_EMP A
 INNER JOIN DEPT_AVG B
    ON A.DEPTNO = B.DEPTNO;

임시 테이블 여러 개를 만든 느낌으로 SQL을 구성할 수 있다.


4. 성능이 좋아질까?

  • WITH절은 무조건 성능 향상이 좋아지는 것은 아니다.
  • 기본적으로 WITH절은 가독성과 유지보수가 목적이다.
  • 오라클 옵티마이저가 내부적으로 서브쿼리처럼 처리한다.

5. WITH절 사용 시 주의사항

  • WITH절은 SELECT문에만 사용이 가능하다.
  • INSERT, UPDATE, DELETE에서도 SELECT와 함께 사용은 가능하다.
  • 너무 많은 WITH절남용은 오히려 가독성이 떨어진다.
  • 임시 테이블이 아니라 실행 시점에만 존재하니 주의하자...!

마무리

WITH절은 단순한 문법이지만 SQL의 재사용성 유지보수 측면에서는 좋은 것 같다. 처음에서는 서브쿼리가 익숙해질 수 있지만 쿼리가 길어질수록 WITH절의 장점은 분명하다...! 복잡한 SQL을 깔끔하게 정리할 때, 동일한 서브쿼리를 여러 번 사용할 때, 다만 위에서 정리한 것 같이 주의사항을 문명 하게 이해하자. 남용은 오히려 정말 가독성이 떨어진다...! 무엇이든 상황에 맞게 사용하자. 감사합니다. (_ _)