자주 쓰는 SQL 윈도우 함수와 이를 제어하는 절을 용도별로 정리했습니다: 행 순위 매기기, 이웃 행 살펴보기, 프레임 전체 누적 계산, 첫 값·마지막 값 가져오기. 각 행은 함수와 한 줄 예시를 짝지어 보여줍니다.
윈도우 함수는 현재 행과 관련된 행 전체에 걸쳐 결과를 계산합니다. GROUP BY처럼 행을 축소하지 않습니다. 모든 윈도우 함수는 OVER 절로 끝나며 이 절이 윈도우를 정의합니다: PARTITION BY는 행을 그룹으로 나누고, ORDER BY는 순서를 정하며, 선택적인 프레임이 움직이는 집합의 경계를 정합니다. OVER를 익히면 나머지는 어휘를 익히는 일입니다.
참고 표 · 27 항목
SQL 윈도우 함수Explained
27 of 27 rows
순위 매기기
윈도우 안의 각 행에 고유한 연속 정수.
ROW_NUMBER() OVER (ORDER BY total DESC)
간격이 있는 순위. 동점은 같은 순위를 공유하고 다음 번호를 건너뜁니다.
RANK() OVER (ORDER BY total DESC)
간격이 없는 순위. 동점은 같은 순위를 공유하며 건너뛰는 번호가 없습니다.
DENSE_RANK() OVER (ORDER BY total DESC)
정렬된 윈도우를 크기가 거의 같은 n개의 버킷으로 나눕니다.
NTILE(4) OVER (ORDER BY total DESC)
이웃 행 살펴보기
n행 이전의 값. 해당 행이 없으면 기본값이 대신 들어갑니다.
LAG(total, 1, 0) OVER (ORDER BY created_at)
n행 이후의 값. 해당 행이 없으면 기본값이 대신 들어갑니다.
LEAD(total, 1, 0) OVER (ORDER BY created_at)
윈도우 집계
행을 축소하지 않는 누적 또는 파티션별 합계.
SUM(total) OVER (ORDER BY created_at)
누적 또는 파티션별 평균.
AVG(total) OVER (PARTITION BY user_id)
누적 또는 파티션별 행 수.
COUNT(*) OVER (PARTITION BY user_id)
윈도우 또는 파티션 전체에서 가장 낮은 값.
MIN(total) OVER (PARTITION BY user_id)
윈도우 또는 파티션 전체에서 가장 높은 값.
MAX(total) OVER (PARTITION BY user_id)
ORDER BY와 시작점이 열린 프레임을 쓰는 SUM. 각 행은 자기까지의 모든 값을 더합니다.
SUM(total) OVER (ORDER BY created_at ROWS UNBOUNDED PRECEDING)
현재 행 앞뒤 n행으로 이루어진 프레임에 대한 AVG.
AVG(total) OVER (ORDER BY created_at ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING)
첫 값, 마지막 값, 백분위
윈도우 정렬 순서에서 첫 번째 값.
FIRST_VALUE(total) OVER (ORDER BY total DESC)
프레임에서 마지막 값. UNBOUNDED FOLLOWING이 없으면 프레임은 현재 행에서 멈춥니다.
LAST_VALUE(total) OVER (ORDER BY total ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
윈도우 정렬 순서의 n번째 행에 있는 값.
NTH_VALUE(total, 2) OVER (ORDER BY total DESC)
행의 상대 순위. 0부터 1까지.
PERCENT_RANK() OVER (ORDER BY total)
현재 행까지 포함한 행의 비율. 1/n부터 1까지.
CUME_DIST() OVER (ORDER BY total)
OVER 절
모든 함수가 읽는 윈도우를 정의합니다.
<fn>() OVER (PARTITION BY user_id ORDER BY created_at)
행 그룹마다 윈도우를 다시 시작합니다.
PARTITION BY user_id
각 파티션 안의 행에 순서를 정합니다.
ORDER BY created_at
움직이는 프레임의 경계를 정합니다. 예: 이전 행부터 이후 행까지.
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
행 위치가 아니라 값으로 프레임 경계를 정합니다. CURRENT ROW는 동점 행을 포함하며, ORDER BY가 있을 때의 기본 프레임입니다.
RANGE BETWEEN 100 PRECEDING AND CURRENT ROW
ORDER BY의 동점 행 그룹 단위로 프레임 경계를 정합니다.
GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW
현재 행을 프레임에서 제외합니다. EXCLUDE TIES는 대신 동점 행들을 제외합니다.
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW
쿼리당 한 번만 윈도우에 이름을 지어 여러 OVER 절이 재사용하게 합니다.
WINDOW w AS (PARTITION BY user_id ORDER BY created_at)
윈도우가 적용되기 전에 윈도우 집계가 읽을 행을 좁힙니다.
SUM(total) FILTER (WHERE status = 'paid') OVER (ORDER BY created_at)