자격증/SQLD

SQLD 윈도우 함수 정리 (RANK·DENSE_RANK 구분)

공감(공부하는감자) 2026. 7. 1. 11:45

안녕하세요, 공부하는 감자입니다 🥔

윈도우 함수 문제를 풀 때 제가 쓰는 방법은 하나뿐이에요. 결과 표를 직접 한 줄씩 채우기. 머릿속으로만 추정하면 꼭 한 칸씩 틀립니다.

그리고 시험이 묻는 포인트는 거의 정해져 있어요. 동점 처리 방식과 PARTITION BY의 동작, 이 둘입니다.

SQLD 2과목에서 윈도우 함수는 매회 2~3문제가 나옵니다. 난이도 표기는 '상'이지만 패턴이 고정이라, 한 번 잡아두면 오히려 안정적인 점수원이에요.

벼락치기 때 버리는 영역으로 분류하는 분들이 많은데, 이해 비용 대비 효율은 좋은 편입니다.

집계 함수와 뭐가 다른가

SUM, COUNT 같은 집계 함수는 여러 행을 하나로 합치죠. 윈도우 함수는 행 수를 그대로 두고 각 행 옆에 계산 결과를 붙입니다.

-- 집계: 팀별 평균 (행이 팀 수만큼으로 줄어듦)
SELECT team_id, AVG(score) FROM PLAYERS GROUP BY team_id;

-- 윈도우: 각 행 옆에 팀 평균을 붙임 (행 수 유지)
SELECT player_name, team_id, score,
       AVG(score) OVER (PARTITION BY team_id) AS team_avg
  FROM PLAYERS;

기본 골격은 함수() OVER (PARTITION BY 그룹 ORDER BY 정렬)입니다.

순위 3종 — 시험의 8할

점수 테이블로 보겠습니다.

player_name score
미나 95
준호 88
하늘 88
태양 75
SELECT player_name, score,
  RANK()       OVER (ORDER BY score DESC) AS rk,
  DENSE_RANK() OVER (ORDER BY score DESC) AS drk,
  ROW_NUMBER() OVER (ORDER BY score DESC) AS rn
FROM PLAYERS;
player_name score rk drk rn
미나 95 1 1 1
준호 88 2 2 2
하늘 88 2 2 3
태양 75 4 3 4

88점 동점자 두 명 다음에 오는 태양의 순위를 보세요. RANK는 4(동점 수만큼 건너뜀), DENSE_RANK는 3(연속).

이 한 칸 차이가 시험에 무조건 나옵니다.

동점 다음 번호를 건너뛰면 RANK, 이어 가면 DENSE_RANK, 동점이어도 전부 다른 번호면 ROW_NUMBER.

ROW_NUMBER는 같은 값에도 서로 다른 번호를 매긴다는 점을 기억하세요. 동점을 같은 순위로 표시하고 싶다면 RANK 계열을 써야 합니다.

PARTITION BY — 있고 없고의 차이

PARTITION BY는 GROUP BY처럼 그룹을 나누지만 행 수는 안 줄입니다. 그룹 안에서 계산만 다시 해요.

SELECT player_name, team_id, score,
  RANK() OVER (PARTITION BY team_id ORDER BY score DESC) AS team_rank
FROM PLAYERS;
player_name team_id score team_rank
미나 A 95 1
준호 A 88 2
하늘 B 88 1
태양 B 75 2

팀 A와 B 안에서 각각 1위부터 다시 셉니다. PARTITION BY를 빼면 전체에서 한 번에 순위를 매기고요.

문제에서 "부서별 순위"라고 했는데 보기 쿼리에 PARTITION BY가 없다? 그게 바로 오답 보기입니다.

LAG / LEAD — 앞뒤 행 훔쳐보기

같은 정렬 안에서 n행 이전(LAG)·이후(LEAD) 값을 가져옵니다. 월별 매출로 보면:

SELECT sale_month, revenue,
  LAG(revenue, 1)  OVER (ORDER BY sale_month) AS prev_rev,
  LEAD(revenue, 1) OVER (ORDER BY sale_month) AS next_rev
FROM MONTHLY_SALES;
sale_month revenue prev_rev next_rev
1월 120 NULL 90
2월 90 120 150
3월 150 90 NULL

첫 행의 LAG와 마지막 행의 LEAD는 NULL이에요. 전월 대비 증감 같은 문제에서 이 경계 NULL을 빼먹으면 결과 행 계산이 틀어집니다.

집계 함수 + OVER = 누적 계산

SUM, AVG, MAX, MIN도 OVER를 붙이면 윈도우 함수가 됩니다. 특히 OVER 안에 ORDER BY가 있으면 기본 범위가 "첫 행부터 현재 행까지"라서 누적 합계가 돼요.

SELECT sale_month, revenue,
  SUM(revenue) OVER (ORDER BY sale_month) AS running_total
FROM MONTHLY_SALES;
sale_month revenue running_total
1월 120 120
2월 90 210
3월 150 360

첫 행부터 현재 행까지의 합이 그대로 쌓여 내려가는 게 보이시죠.

자주 깨지는 지점들

  • RANK/DENSE_RANK 혼동 — 오답 1순위. "건너뛰기 vs 연속"
  • ROW_NUMBER에 동점 기대 — 같은 값도 다른 번호입니다
  • OVER 절 없이 SELECT RANK() FROM ... — 문법 오류예요. RANK 계열은 OVER가 필수
  • ORDER BY 방향 안 보기 — ASC인지 DESC인지에 따라 순위가 뒤집힙니다

풀이 순서는 이렇게 굳히세요. PARTITION BY 유무 확인 → ORDER BY 컬럼과 방향 확인 → 동점 처리 규칙 적용 → 결과 표를 손으로 채우기.

보기에서 눈으로 고르려 하지 말고 무조건 표로 재구성하는 게 안전합니다.

이 유형은 손으로 채워보는 반복 연습이 전부라서, 저는 모의고사에서 윈도우 함수 문제만 골라 여러 번 다시 풀었어요. 문어CBT 무료 모의고사에 이 유형이 회차마다 들어 있어서 연습량 채우기엔 충분했습니다.

 

SQLD·정처기·컴활·ADsP 무료 CBT 모의고사

기출 변형 문제, 자동 채점, 회차별 실력 추적까지 가입 없이 바로 풀어보세요.

sqldpass.com

동점 처리 한 칸, PARTITION 유무 하나. 윈도우 함수 문제의 정답은 늘 이 두 군데서 갈립니다.