중첩 쿼리를 CTE로 리팩터링하기
실시간 면접에서 읽기 어려운 중첩 쿼리를 단계별 CTE로 바꾸는 패턴을 익힙니다.
중첩 쿼리를 CTE로 리팩터링하기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
실시간 면접 리팩터링
중급 면접에서 자주 나오는 과제는 다음과 같습니다. 여기 쿼리가 있습니다. 읽기 쉽게 바꿔 보세요. 면접관은 깊게 중첩된 SELECT를 건네고 여러분이 어떻게 분해하는지 지켜봅니다. 중첩을 이름이 지정된 CTE의 순서로 바꾸는 것이 가장 깔끔한 답입니다.
이 레슨에서는 화이트보드 앞에서도 침착하게 수행할 수 있도록 정확한 작업 순서를 살펴봅니다.
가장 안쪽 쿼리부터 시작하기
중첩된 하위 쿼리는 개념적으로 안쪽에서 바깥쪽 순서로 실행됩니다. 따라서 쿼리도 안쪽부터 읽으세요. 가장 깊이 있는 괄호 안의 SELECT를 먼저 찾으면 그것이 첫 번째 파이프라인 단계입니다.
설명적인 이름을 지정하고 이를 CTE로 끌어올리세요. 이제 그 안쪽 블록을 참조하던 모든 부분은 대신 CTE 이름을 참조하게 됩니다.
SELECT *
FROM (
SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
) t
WHERE t.total > 1000;한 단계 위로 끌어올려 CTE로 만들기
가장 안쪽의 파생 테이블을 가져와 CTE로 승격하세요. 바깥쪽 쿼리는 이름이 지정된 CTE에서 선택하도록 바뀌는 것 외에는 그대로 유지됩니다.
이 한 번의 작업만으로도 머릿속으로 중첩을 풀어야 하는 단계가 하나 줄어들고, 해당 단계에 의미 있는 이름이 생깁니다.
WITH spend AS (
SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
)
SELECT *
FROM spend
WHERE total > 1000;실제로 중첩된 예제
리팩터링하기 더 어려운 예제를 살펴보겠습니다. 두 단계의 중첩과 상관 하위 쿼리와 같은 필터가 함께 있습니다. 목표는 지출액이 가장 높은 등급에 속한 고객들의 평균 주문 금액을 구하는 것입니다.
올바른 쿼리이지만 읽기 어렵습니다. 이제 단계별로 분해해 보겠습니다.
SELECT AVG(o.amount) AS avg_order
FROM orders o
WHERE o.customer_id IN (
SELECT customer_id
FROM (
SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
) s
WHERE s.total > 1000
);첫 번째 단계에 이름 지정하기
가장 안쪽 블록은 고객별 총 지출액을 계산합니다. 이를 spend라는 CTE로 끌어올리세요. 이제 중간 계층에서는 해당 CTE를 간단히 필터링합니다.
추출할 때마다 중첩 깊이가 한 단계 줄어들고 자체적으로 설명하는 이름이 추가된다는 점에 주목하세요.
WITH spend AS (
SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
)
SELECT AVG(o.amount) AS avg_order
FROM orders o
WHERE o.customer_id IN (
SELECT customer_id FROM spend WHERE total > 1000
);두 번째 단계에 이름 지정하기
spend에 적용되는 필터를 별도의 CTE인 big_spenders로 추출하세요. 그러면 남은 주 쿼리는 이름이 명확한 집합에 대한 평평한 조인 또는 멤버십 확인이 됩니다.
이제 각 단계가 하나의 책임만 가지며, 이는 깔끔한 SQL의 대표적인 특징입니다.
WITH spend AS (
SELECT customer_id, SUM(amount) AS total
FROM orders GROUP BY customer_id
),
big_spenders AS (
SELECT customer_id FROM spend WHERE total > 1000
)
SELECT AVG(o.amount) AS avg_order
FROM orders o
JOIN big_spenders b ON b.customer_id = o.customer_id;리팩터링하면서 의미 보존하기
황금률은 리팩터링이 결과를 변경해서는 안 된다는 것입니다. 출력 결과를 조용히 바꿀 수 있는 함정을 주의하세요.
IN을JOIN으로 바꾸면 오른쪽이 고유하지 않은 경우 중복 행이 생길 수 있습니다.- NULL이 포함된
NOT IN은NOT EXISTS와 다르게 동작합니다. - 집계 단위는 그대로 유지되어야 합니다.
이러한 위험을 소리 내어 설명하면 신중하게 작업한다는 점을 보여 줄 수 있습니다.
리팩터링 검증하기
리팩터링이 원래 동작을 충실하게 유지하는지 어떻게 증명하시겠습니까? 두 버전을 모두 실행한 뒤 행 개수와 체크섬을 비교하거나, 표본의 결과 집합을 비교한다고 말씀해 보십시오.
면접에서 개수와 몇 개의 표본 행을 비교해서 검증하겠습니다라고 설명하는 것만으로도 단순히 구문을 다시 작성하는 것 이상의 공학적 규율을 보여 줄 수 있습니다.
SELECT COUNT(*), SUM(amount)
FROM orders
WHERE customer_id IN (SELECT customer_id FROM big_spenders);리팩터링하지 말아야 할 때
리팩터링이 항상 개선을 의미하는 것은 아닙니다. 단순한 하위 쿼리 하나는 그대로 두는 편이 더 명확할 수 있으며, 너무 많은 작은 CTE로 나누는 것 역시 가독성을 해칠 수 있습니다.
판단력을 발휘하십시오. 중첩 때문에 의도가 흐려지거나 논리를 재사용할 때 리팩터링하십시오. 쿼리가 위에서 아래로 명확한 이름이 붙은 단계들로 읽히는 순간 멈추겠다고 면접관에게 말해 보십시오.
리팩터링 점검 목록
외워서 말할 수 있는 반복 가능한 방법은 다음과 같습니다.
- 안쪽에서 바깥쪽으로 읽으며 가장 깊은 하위 쿼리를 찾습니다.
- 그 하위 쿼리를 이름이 붙은 CTE로 끌어올립니다.
- 한 번에 한 계층씩 위로 올라가며 반복합니다.
- 각 단계가 만들어 내는 결과에 따라 이름을 정합니다.
- 결과가 바뀌지 않았는지 확인합니다(IN/JOIN과 NULL의 함정에 주의하십시오).
이렇게 하면 겁나는 중첩 쿼리를 차분하고 단계적인 재작성으로 바꿀 수 있습니다.
리팩터링 설명하기
작업하면서 소리 내어 설명하십시오. 가장 안쪽 블록은 고객별 지출이므로 spend라고 부르겠습니다. 다음 계층에서는 지출이 큰 고객을 필터링합니다. 그런 다음 바깥쪽 쿼리에서 이 고객들의 주문 금액 평균을 계산합니다.
면접관은 정답만큼 의사소통 능력도 평가합니다. 단계별로 설명하면서 진행하는 리팩터링은 면접관이 원하는 중급 수준의 성숙도를 정확히 보여 줍니다.
빠른 확인
깊게 중첩된 쿼리를 CTE로 리팩터링할 때 올바른 첫 단계를 찾아보십시오.
복습: CTE로 리팩터링하기
안쪽에서 바깥쪽으로 읽고, 가장 깊은 하위 쿼리를 이름이 붙은 CTE로 끌어올린 다음, 한 번에 한 계층씩 바깥으로 작업하는 차분하고 반복 가능한 리팩터링 방법을 배웠습니다.
- 각 단계가 만들어 내는 결과에 따라 이름을 정합니다.
- 의미를 보존하고, IN과 JOIN의 중복 및 NULL의 함정에 주의합니다.
- 개수와 표본 행을 비교하여 검증합니다.
- 너무 많이 나누지 말고, 쿼리가 명확한 이름이 붙은 단계로 읽히는 시점에 멈춥니다.
이로써 CTE 과정을 마쳤습니다. 이제 실제 면접에서 자신 있게 리팩터링할 수 있습니다.
자주 묻는 질문
“중첩 쿼리를 CTE로 리팩터링하기” 강의는 무료인가요?
네 — “중첩 쿼리를 CTE로 리팩터링하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“중첩 쿼리를 CTE로 리팩터링하기”에서 뭘 배우나요?
실시간 면접에서 읽기 어려운 중첩 쿼리를 단계별 CTE로 바꾸는 패턴을 익힙니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“중첩 쿼리를 CTE로 리팩터링하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 첫 번째 CTE 작성하기
- 여러 CTE 연결하기
- CTE, 하위 쿼리와 임시 표 비교하기
- 중첩 쿼리를 CTE로 리팩터링하기