728x90

MSSQL 서브쿼리와 CTE 활용법 – 복잡한 쿼리를 간결하게 만드는 방법
SQL에서 복잡한 조건이나 가공 데이터를 조회할 때 서브쿼리(Subquery)와 CTE(Common Table Expression)는 매우 유용하게 사용됩니다.
둘 다 중간 결과를 재사용하거나 가독성을 높이는 데 효과적이지만, 쓰임새와 문법에서 차이가 있습니다.
1. 서브쿼리(Subquery)란?
서브쿼리는 또 다른 쿼리 내부에 포함된 쿼리로, SELECT, FROM, WHERE 절 등에서 사용됩니다.
▶ 예: WHERE 절에서 사용
SELECT UserName
FROM Users
WHERE UserId IN (
SELECT UserId
FROM Orders
WHERE TotalAmount >= 50000
);
▶ 예: SELECT 절에서 사용
SELECT UserName,
(SELECT COUNT(*)
FROM Orders
WHERE Orders.UserId = Users.UserId) AS OrderCount
FROM Users;
▶ 예: FROM 절에서 사용 (인라인 뷰)
SELECT TopUsers.UserId, TopUsers.TotalSpent
FROM (
SELECT UserId, SUM(TotalAmount) AS TotalSpent
FROM Orders
GROUP BY UserId
) AS TopUsers
WHERE TotalSpent > 100000;
2. CTE(Common Table Expression)란?
CTE는 WITH 절을 사용하여 중간 결과를 이름으로 정의하고, 해당 결과를 SELECT, JOIN, 재귀 처리 등에 활용할 수 있는 구조입니다.
▶ 기본 문법
WITH 중간이름 AS (
SELECT ...
)
SELECT ...
FROM 중간이름;
▶ 예제: 사용자별 주문 합계를 CTE로 재사용
WITH UserOrders AS (
SELECT UserId, SUM(TotalAmount) AS TotalSpent
FROM Orders
GROUP BY UserId
)
SELECT u.UserName, uo.TotalSpent
FROM UserOrders uo
JOIN Users u ON u.UserId = uo.UserId
WHERE uo.TotalSpent >= 50000;
▶ 재귀 CTE 예 (계층 구조 처리)
WITH OrgChart AS (
SELECT EmployeeId, ManagerId, 1 AS Level
FROM Employees
WHERE ManagerId IS NULL
UNION ALL
SELECT e.EmployeeId, e.ManagerId, Level + 1
FROM Employees e
INNER JOIN OrgChart o ON e.ManagerId = o.EmployeeId
)
SELECT * FROM OrgChart;
재귀 CTE는 조직도, 트리 구조, 카테고리 분류 등 계층형 데이터를 처리할 때 유용합니다.
3. 서브쿼리 vs CTE 차이점
| 구분 | 서브쿼리 | CTE |
|---|---|---|
| 작성 위치 | SELECT, WHERE, FROM 절 내 | WITH 절에서 정의 후 사용 |
| 가독성 | 복잡한 경우 읽기 어려움 | 가독성이 높고 깔끔함 |
| 재사용성 | 한 번만 사용 | 여러 번 참조 가능 |
| 재귀 처리 | 불가 | 가능 (재귀 CTE) |
4. 실무 팁 💡
- 간단한 필터링이나 조건 비교에는 서브쿼리가 편리하지만, 복잡한 그룹핑, 재사용, 재귀 처리에는 CTE를 사용하는 것이 좋습니다.
- 여러 개의 CTE를
WITH A AS (...), B AS (...)식으로 나열해 사용할 수도 있습니다. - CTE는 뷰(View)처럼 재사용되지만 일시적인 쿼리 범위에 한정되므로, 성능 튜닝 시 실행 계획을 꼭 확인하세요.
마무리
서브쿼리와 CTE는 복잡한 데이터 조회를 간결하게 만들 수 있는 강력한 도구입니다.
두 방법을 상황에 맞게 적절히 활용하면, 쿼리 성능과 유지보수 측면에서도 큰 이점을 얻을 수 있습니다.
728x90
'Database > MSSQL' 카테고리의 다른 글
| MSSQL 자주 사용하는 문자열 함수(LEN, SUBSTRING 등) 정리 (0) | 2025.05.25 |
|---|---|
| MSSQL 윈도우 함수(OVER, RANK 등) 사용 예제 (0) | 2025.05.24 |
| MSSQL GROUP BY와 HAVING 절의 차이점과 사용법 (0) | 2025.05.22 |
| MSSQL INSERT, UPDATE, DELETE 문 사용법 (0) | 2025.05.21 |
| MSSQL SELECT 문 기본 사용법과 WHERE 절 활용 (0) | 2025.05.20 |