How To

SQL 윈도우 함수 실전 가이드 - 데이터 분석가 필수 쿼리

SQL 윈도우 함수, GROUP BY로는 안 풀리는 문제를 해결하는 핵심 도구예요. ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD, 누적 합계와 이동 평균까지 실무 예제 쿼리로 정리했어요. 데이터 분석가 면접과 실무에서 바로 쓸 수 있는 SQL 문법을 확인해보세요.
2026.07.10
SQL 윈도우 함수 실전 가이드 - 데이터 분석가 필수 쿼리

"부서별로 매출이 가장 높은 직원과 그 매출액을 한 행에 같이 보여줘 주세요."

이런 요청을 받으면 막막해지신 적 있으신가요? GROUP BY로 부서별 최댓값은 구할 수 있지만, 그 최댓값을 낸 직원 이름까지 같은 행에 담으려면 서브쿼리를 여러 겹 겹치게 되죠. 이럴 때 필요한 게 바로 윈도우 함수예요.

윈도우 함수는 SQL 실무와 면접에서 초급과 중급 실력자를 가르는 대표적인 기준으로 꼽혀요. GROUP BY만 알고 있는 분과, OVER()까지 다룰 줄 아는 분은 풀 수 있는 문제의 범위 자체가 달라져요. 이번 글에서 개념부터 실무에서 바로 쓸 수 있는 예제 쿼리까지 정리해볼게요.

1. 윈도우 함수란 무엇인가요?

윈도우 함수는 행들을 특정 그룹(윈도우)으로 묶어서 계산하면서도, GROUP BY와 달리 원본 행을 그대로 유지하는 함수예요. 집계 함수와 달리 윈도우 함수는 결과가 하나의 행으로 합쳐지지 않고, 각 행이 자신의 정체성을 그대로 유지한 채로 순위·누적합·이전 행과의 비교 같은 계산이 추가로 붙는 방식이에요[3].

즉, "부서별 평균 매출은 얼마인가요?"처럼 행이 하나로 줄어드는 질문은 GROUP BY로 충분하지만, "각 직원의 매출과 함께 그 직원이 부서 내에서 몇 위인지도 같이 보여줘 주세요"처럼 원본 행 + 추가 계산값이 동시에 필요한 질문은 윈도우 함수가 답이에요.

2. OVER(), PARTITION BY, ORDER BY 기본 문법

윈도우 함수의 기본 구조는 다음과 같아요[1][2].

함수명(...) OVER (
  PARTITION BY 그룹기준컬럼
  ORDER BY 정렬기준컬럼
)
  • OVER(): 이 함수가 윈도우 함수임을 알리고, 계산 범위를 정의하는 부분이에요. OVER()만 있고 PARTITION BY / ORDER BY가 없으면 테이블 전체가 하나의 그룹이 돼요.

  • PARTITION BY: 행들을 소그룹으로 나누는 기준이에요. 예를 들어 PARTITION BY department라면 부서별로 각각 별도의 계산이 이루어져요.

  • ORDER BY: 그룹(파티션) 안에서 행의 순서를 정해요. 순위 함수에서는 순위를 매기는 기준이 되고, 누적합/이동평균 같은 계산에서는 어떤 순서로 누적할지를 결정해요.

참고로 윈도우 함수는 SELECT 절과 ORDER BY 절에서만 사용할 수 있고, WHERE·GROUP BY·HAVING 절에는 직접 쓸 수 없다는 점도 알아두면 좋아요[1]. 윈도우 함수로 계산한 값을 다시 필터링하려면 서브쿼리로 한 번 감싸야 해요. (4장에서 실제로 이 패턴을 사용해요.)

3. 데이터 분석가가 가장 많이 쓰는 윈도우 함수

3.1 ROW_NUMBER — 그룹 내 고유 순번

ROW_NUMBER()는 파티션 안에서 각 행에 중복 없는 고유한 순번을 1부터 매겨요[1][2]. 값이 같아도 무조건 다른 번호가 부여돼요.

SELECT
  department,
  employee,
  amount,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY amount DESC) AS rn
FROM sales;

3.2 RANK / DENSE_RANK — 동점을 처리하는 순위

RANK()DENSE_RANK()는 동점(peer)에게 같은 순위를 부여한다는 점은 같지만, 그다음 순위를 매기는 방식이 달라요[1][2].

  • RANK(): 동점 다음 순위에 공백(gap) 이 생겨요. 1등이 2명이면 다음은 3등이에요.

  • DENSE_RANK(): 동점 다음 순위가 연속으로 이어져요. 1등이 2명이어도 다음은 2등이에요.

SELECT
  department,
  employee,
  amount,
  RANK() OVER (PARTITION BY department ORDER BY amount DESC) AS rank_no,
  DENSE_RANK() OVER (PARTITION BY department ORDER BY amount DESC) AS dense_rank_no
FROM sales;

3.3 LAG / LEAD — 이전/다음 행 값 가져오기

LAG()는 현재 행 기준으로 이전 행의 값을, LEAD()는 다음 행의 값을 가져와요[1][2]. 전월 대비 증감처럼 "바로 앞/뒤 데이터와 비교"할 때 자주 써요.

SELECT
  department,
  sale_month,
  monthly_amount,
  LAG(monthly_amount, 1) OVER (PARTITION BY department ORDER BY sale_month) AS prev_month_amount,
  monthly_amount - LAG(monthly_amount, 1) OVER (PARTITION BY department ORDER BY sale_month) AS mom_change
FROM monthly_sales;

3.4 SUM / AVG OVER — 누적 합계와 이동 평균

집계 함수도 OVER를 붙이면 윈도우 함수로 동작해요[1][2]. ORDER BY만 주면 누적 합계가 되고, ROWS BETWEEN으로 범위를 지정하면 이동 평균을 만들 수 있어요.

-- 누적 합계
SELECT
  sale_date,
  daily_amount,
  SUM(daily_amount) OVER (ORDER BY sale_date) AS running_total
FROM daily_sales;

-- 7일 이동 평균
SELECT
  sale_date,
  daily_amount,
  AVG(daily_amount) OVER (
    ORDER BY sale_date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) AS moving_avg_7d
FROM daily_sales;

3.5 NTILE — 그룹을 N등분

NTILE(n)은 파티션 안의 행을 순서대로 최대한 균등하게 n개의 그룹으로 나눠요[1][2]. 상위 25% 고객, 매출 4분위 구간 나누기처럼 분위수 분석에 유용해요.

SELECT
  employee,
  amount,
  NTILE(4) OVER (ORDER BY amount DESC) AS quartile
FROM sales;

요약 표

함수

용도

실무 예시

ROW_NUMBER()

그룹 내 고유 순번 부여

그룹별 최신 행 하나만 남기기(중복 제거)

RANK()

동점 허용 순위, 동점 뒤 순위 건너뜀

카테고리별 매출 순위

DENSE_RANK()

동점 허용 순위, 건너뜀 없이 연속

동점자가 많은 항목 순위 매기기

LAG() / LEAD()

이전/다음 행 값 조회

전월 대비 매출 증감률

SUM() OVER

누적 합계

일별 누적 매출

AVG() OVER

이동 평균

7일 이동평균 매출

NTILE(n)

그룹을 N등분

매출 상위 25% 고객 추출

4. 실무 활용 사례 3가지

4.1 그룹별 최신 레코드만 남기기 (중복 제거)

같은 사용자가 여러 번 정보를 갱신한 로그성 테이블에서, 사용자별 가장 최근 행만 남기고 싶을 때 자주 쓰는 패턴이에요[3]. ROW_NUMBER()로 순번을 매긴 뒤, 서브쿼리로 감싸서 rn = 1인 행만 필터링해요.

SELECT *
FROM (
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC) AS rn
  FROM user_profiles
) t
WHERE rn = 1;

4.2 카테고리 내 순위 매기기 (카테고리별 매출 TOP 3)

전체 상품 중 순위가 아니라 카테고리별로 상위 몇 개만 뽑고 싶을 때, PARTITION BY category로 그룹을 나누고 RANK()로 순위를 매긴 다음 필터링하면 돼요.

SELECT *
FROM (
  SELECT
    category,
    product_name,
    total_sales,
    RANK() OVER (PARTITION BY category ORDER BY total_sales DESC) AS category_rank
  FROM product_sales
) t
WHERE category_rank <= 3;

4.3 누적 합계 / 이동 평균으로 트렌드 보기

일별 매출이 들쭉날쭉할 때, 하루 값만 보면 트렌드가 잘 안 보여요. 앞서 3.4에서 본 SUM() OVER로 누적 매출을, AVG() OVER ... ROWS BETWEEN으로 7일 이동평균을 같이 뽑으면 단기 변동을 걸러낸 추세를 확인할 수 있어요. 리텐션 분석에서 코호트별 누적 잔존 사용자 수를 볼 때도 같은 패턴이 쓰여요.

5. 왜 지금 배워야 할까요?

윈도우 함수는 SQL 인터뷰에서 자주 등장하는 주제로 알려져 있어요[4]. 순위를 매기는 문제, 중복을 제거하는 문제, 누적 합계를 구하는 문제는 GROUP BY만으로는 깔끔하게 풀리지 않기 때문에, 지원자가 실무형 SQL을 다룰 수 있는지 확인하는 용도로 즐겨 쓰이는 편이에요[4].

그리고 이건 면접만을 위한 스킬이 아니에요. 대시보드에서 "카테고리별 TOP N", "전주 대비 증감", "코호트 리텐션" 같은 요청은 실무에서 정말 자주 나오고, 그때마다 서브쿼리를 여러 겹 쌓는 대신 윈도우 함수 한 줄로 해결할 수 있어요. 트리업의 기술 가이드에서 SQL 학습 로드맵을 확인하면서, 오늘 배운 예제들을 실제 테이블에 직접 돌려보는 걸 추천해요.

마무리

GROUP BY로 행이 줄어드는 문제와, 원본 행을 유지하면서 순위·누적·비교가 필요한 문제는 다른 도구가 필요해요. 그 경계에서 있는 게 바로 윈도우 함수예요. ROW_NUMBER, RANK, DENSE_RANK, LAG/LEAD, SUM/AVG OVER, NTILE — 이 7가지만 확실히 익혀도 대부분의 실무·면접 쿼리를 커버할 수 있어요.

한 번에 다 외우려 하지 말고, 오늘 나온 예제 쿼리를 하나씩 직접 실행해보면서 익혀보세요. 작은 연습들이 쌓이면 어느새 서브쿼리 대신 OVER()가 먼저 떠오르는 순간이 올 거예요.

윈도우함수
데이터분석
SQL인터뷰
SQL
데이터분석가
Updated 2026.07.10

Recommended for you

  • REST API 설계 원칙 - 면접에도 나오는 좋은 API의 조건
    How To
    REST API 설계는 실무 감각이자 면접 단골 소재예요. URI 네이밍 규칙, HTTP 메서드별 멱등성과 안전성, 상태 코드, 버전 관리, HATEOAS까지 주니어 개발자가 알아야 할 원칙을 한 번에 정리했어요.
  • Docker 입문 - 신입 개발자가 처음 컨테이너를 다루는 법
    How To
    채용 공고마다 "Docker 사용 경험 우대"가 보이는데 써본 적 없다면? 컨테이너와 가상머신의 차이, 이미지·Dockerfile 개념부터 build/run 명령어, 직접 따라 하는 미니 실습까지 신입 개발자 눈높이로 정리했어요. 오늘 바로 컨테이너 하나 실행해볼 수 있어요.
  • Git 브랜치 전략 완전 정복 - 신입이 꼭 알아야 할 협업 워크플로우
    How To
    Git commit, push는 익숙한데 팀 협업은 처음이신가요? Git Flow, GitHub Flow, GitLab Flow, Trunk-Based Development까지 4가지 브랜치 전략의 구조와 장단점, 실제 브랜치 이름 예시를 비교표로 정리했어요. 신입 개발자를 위한 실전 체크리스트도 확인해보세요.
  • PostgreSQL vs MySQL, 신입 개발자는 뭘 선택해야 할까요?
    Tool Comparison
    PostgreSQL과 MySQL, 실무에서는 정말 뭘 선택해야 할까요? 2025 Stack Overflow 개발자 설문 데이터와 ACID·JSON·라이선스 같은 실무 차이, 카카오뱅크·BC카드 등 국내 기업 사례까지 신입 개발자 눈높이에서 꼼꼼하게 비교해봤어요.
  • Pandas vs Polars, 데이터 분석가는 이제 뭘 써야 할까
    Tool Comparison
    Pandas와 Polars, 실제로 얼마나 다를까요? Polars 공식 벤치마크와 JetBrains 설문, 국내 채용 공고 데이터로 확인한 성능 차이와 문법 차이를 정리했어요. 주니어 데이터 분석가가 지금 당장 무엇을 우선 배워야 하는지 실무 기준으로 알려드려요.
  • Tableau vs Power BI vs Looker, 데이터 분석가라면 뭐부터 배워야 할까요?
    Tool Comparison
    Tableau, Power BI, Looker 중 무엇부터 배워야 할지 고민되는 주니어 데이터 분석가를 위한 글이에요. 가격, 학습 난이도, 글로벌 시장 평가에 더해 한국 채용 공고 실제 검색 데이터까지 꼼꼼히 비교해서 학습 우선순위를 명확하게 정리해드릴게요.