윈도우함수가 무엇인가?
firststep 에디터
IT / 자격증 전문 라이터
윈도우함수가 무엇인가?
윈도우 함수 한 줄 정의
행을 줄이지 않고(=GROUP BY처럼 뭉개지 않고), 각 행 옆에 ‘분석용 값’을 붙이는 함수입니다.
- GROUP BY → 결과 행 수가 줄어듦(집계행만 남음)
- 윈도우 함수 → 원래 행은 그대로 + 옆에 순위/평균/이전값/누적비율 같은 컬럼이 추가됨
1) 윈도우 함수 기본 틀(OVER)
윈도우 함수는 항상 OVER(...)가 붙습니다.
윈도우함수() OVER(
PARTITION BY ... -- 그룹 나누기(부서별, 학급별)
ORDER BY ... -- 그룹 안에서 정렬(급여순, 날짜순)
[WINDOW FRAME] -- “어디까지를 범위로 볼지” (핵심)
)
- PARTITION BY: “부서별로 따로 계산”
- ORDER BY: “부서 안에서 급여순으로 순위/흐름 만들기”
2) 순위 함수: ROW_NUMBER vs RANK vs DENSE_RANK
같은 급여가 있을 때 차이가 납니다.
- ROW_NUMBER(): 무조건 1,2,3… (동점이어도 번호는 다름)
- RANK(): 동점이면 같은 순위, 다음 순위는 건너뜀(1,2,2,4…)
- DENSE_RANK(): 동점이면 같은 순위, 다음 순위는 안 건너뜀(1,2,2,3…)
예)
ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal DESC)
RANK() OVER(PARTITION BY deptno ORDER BY sal DESC)
DENSE_RANK() OVER(PARTITION BY deptno ORDER BY sal DESC)
3) 집계 + OVER: “부서 평균을 각 행에 붙이기”
예) “각 직원 행에 부서 평균 급여를 같이 표시”
AVG(sal) OVER(PARTITION BY deptno) AS dept_avg
이건 수업에서 정말 자주 씁니다.
“나의 급여 vs 우리 부서 평균” 같은 비교를 한 쿼리로 끝냅니다.
4) 행 이동 함수(오프셋): LAG / LEAD
- LAG(sal): 이전 행의 급여(과거)
- LEAD(sal): 다음 행의 급여(미래)
예) 사번 기준으로 다음 사람 급여 보기
LEAD(sal, 1, 0) OVER(ORDER BY empno) AS next_sal
5) FIRST_VALUE / LAST_VALUE: “그룹에서 첫 값/마지막 값”
FIRST_VALUE
정렬 기준으로 첫 번째 값을 가져옵니다.
FIRST_VALUE(sal) OVER(
PARTITION BY deptno
ORDER BY empno
) AS dept_first_sal
LAST_VALUE가 헷갈리는 이유(이미지 핵심)
LAST_VALUE()는 기본 프레임 때문에 “진짜 마지막”이 아니라 현재 행까지의 마지막으로 보이는 경우가 많습니다.
즉, 이렇게 쓰면:
LAST_VALUE(sal) OVER(
PARTITION BY deptno
ORDER BY empno
)
결과가 “마지막 값”이 아니라 내 SAL이 그대로 나오는 것처럼 보일 수 있습니다.
(현재 행이 프레임의 끝이라서 ‘마지막’이 현재 행이 됨)
진짜 “파티션의 마지막 값”을 원하면: 프레임을 전체로 확장
이미지에서 강조한 구문이 이거예요:
LAST_VALUE(sal) OVER(
PARTITION BY deptno
ORDER BY empno
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS dept_last_sal
- UNBOUNDED PRECEDING = 파티션의 맨 처음부터
- UNBOUNDED FOLLOWING = 파티션의 맨 끝까지
→ 파티션 전체를 보고 마지막 값을 제대로 가져옴
6) NTH_VALUE(n): “그룹에서 n번째 값”
정렬 기준으로 n번째 값을 가져옵니다. (n은 1부터)
예) 부서별로 “2번째 사번의 급여”를 모든 행에 붙이기
NTH_VALUE(sal, 2) OVER(
PARTITION BY deptno
ORDER BY empno
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS second_sal
여기서도 프레임을 전체로 잡는 게 안전합니다.
(안 잡으면 “현재 행까지의 n번째” 같은 오해가 생길 수 있음)
7) 비율(분포) 함수 3종: CUME_DIST / PERCENT_RANK / NTILE
이 파트가 이번 추가 이미지의 핵심입니다. “내 위치가 어느 정도냐?”를 수치로 보여줍니다.
7-1) CUME_DIST()
누적 분포 비율입니다.
“나보다 작거나 같은 값이 파티션에서 몇 %냐?”
- 값 범위: (0, 1] 형태로 나오며 보통 1까지 도달
- 직관: “내 급여 이하(<=) 인원이 전체에서 차지하는 비율”
예)
CUME_DIST() OVER(PARTITION BY deptno ORDER BY sal) AS dept_cume_dist
부서에 3명이 있고 내 급여가 중간(2등)이라면
<= 나가 2명 → 2/3 = 0.6666…
7-2) PERCENT_RANK()
백분위 ‘순위 기반’ 비율입니다. 공식이 이미지에 나옵니다.
- 공식: (rank - 1) / (전체행수 - 1)
- 범위: 0 ~ 1
- 특징: “순위의 상대 위치”를 계산
- 1등은 무조건 0
- 마지막은 1
예)
PERCENT_RANK() OVER(PARTITION BY deptno ORDER BY sal) AS dept_percent_rank
CUME_DIST와 차이
- CUME_DIST: “행 개수 기준 누적 비율(<=)” 느낌
- PERCENT_RANK: “순위 기반 위치” 느낌(공식으로 딱 떨어짐)
7-3) NTILE(n)
n개의 구간(등급)으로 나누기입니다. (분위수 나누기)
예) 부서별 급여를 3등급으로 나누기
NTILE(3) OVER(PARTITION BY deptno ORDER BY sal) AS dept_ntile
해석:
- 각 부서에서 급여가 낮은 사람은 1, 중간은 2, 높은 사람은 3 같은 “등급”이 됩니다.
- 데이터 개수가 n으로 딱 안 나눠지면 앞쪽 그룹부터 1명씩 더 가져가는 방식으로 나뉘는 경우가 많습니다.
전체 요약(암기 포인트)
- 윈도우 함수 = 행을 유지하면서 분석 컬럼 추가
- OVER(PARTITION BY, ORDER BY)로 “그룹+정렬”을 만든다.
- LAST_VALUE는 프레임 때문에 함정 → 진짜 마지막이 필요하면
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING - NTH_VALUE는 n번째 값, 프레임 전체 지정하면 안정적
- 비율 함수:
- CUME_DIST: “<= 나”의 누적 비율
- PERCENT_RANK: “순위 기반” 백분위
- NTILE(n): n개 등급으로 쪼개기
firststep 에디터 · IT / 자격증 전문 라이터
firststep.kr의 실무 에디터로서 무언가를 처음 도전하는 분들이 헤매지 않도록 검증된 지식과 실습 가이드를 작성합니다.
댓글 0개
댓글을 작성하려면 로그인이 필요합니다
간단한 이메일과 비밀번호로 3초 만에 가입하고 의견을 남겨보세요.
첫 번째 댓글을 남겨보세요!