MySQL 윈도우 함수(Window Function) 총정리

stone tiger·2025년 3월 5일

MySQL

목록 보기
11/11

MySQL의 윈도우 함수(Window Function)GROUP BY 없이도 행 단위로 집계 연산을 수행
즉, 기존 GROUP BY
한 행으로 축약되지만, 윈도우 함수는 원본 데이터를 유지하면서 계산 결과를 추가**

윈도우 함수는 OVER() 절과 함께 사용되며, 여러 가지 강력한 기능을 제공 🚀


📌 1. 윈도우 함수 기본 구조

윈도우_함수(컬럼) OVER (
    PARTITION BY 컬럼   -- (선택) 그룹별 연산
    ORDER BY 컬럼       -- (선택) 정렬 순서 지정
    ROWS BETWEEN ...    -- (선택) 특정 범위 지정
)
  • PARTITION BY → 그룹별 연산 수행 (예: 부서별 평균 급여)
  • ORDER BY → 특정 순서대로 정렬 후 연산 (예: 누적 합계)
  • ROWS BETWEEN → 특정 범위의 행만 계산 (예: 현재 행 ±2개의 행만 평균 계산)

🔥 2. MySQL 윈도우 함수 종류

카테고리함수설명
누적 및 집계 함수SUM(), AVG(), COUNT(), MAX(), MIN()누적합, 평균, 개수 등 계산
순위(RANK) 함수RANK(), DENSE_RANK(), ROW_NUMBER()순위 매기기
이전/다음 행 참조LAG(), LEAD()이전 행, 다음 행 값 가져오기
백분율 함수PERCENT_RANK(), CUME_DIST()비율(퍼센트) 순위 계산
순번 함수NTILE(n)데이터를 n개의 그룹으로 나누기

3. 기본 집계(Window Aggregate) 함수

SUM(), AVG(), COUNT(), MAX(), MIN() 등의 집계 함수는 윈도우 함수로 사용 가능해!

📌 예제: 누적 합계 (SUM())

SELECT id, name, salary, 
       SUM(salary) OVER (ORDER BY id) AS running_total
FROM employees;

ORDER BY id 순서로 salary누적 합계를 계산

📌 결과

idnamesalaryrunning_total
1Alice50005000
2Bob600011000
3Carol700018000

4. 순위(RANK) 함수

📌 1) RANK() (동순위 발생)

SELECT id, name, salary, 
       RANK() OVER (ORDER BY salary DESC) AS ranking
FROM employees;

salary 기준으로 순위 매기기 (동점일 경우 순위 건너뜀)
✔ 같은 salary면 같은 순위, 다음 순위는 건너뜀 (1, 2, 2, 4, 5)

idnamesalaryranking
1Alice70001
2Bob60002
3Carol60002
4Dave50004

📌 2) DENSE_RANK() (순위 건너뛰지 않음)

SELECT id, name, salary, 
       DENSE_RANK() OVER (ORDER BY salary DESC) AS ranking
FROM employees;

순위가 연속적으로 유지됨 (1, 2, 2, 3, 4)

idnamesalaryranking
1Alice70001
2Bob60002
3Carol60002
4Dave50003

📌 3) ROW_NUMBER() (순위 부여, 중복 없음)

SELECT id, name, salary, 
       ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees;

모든 행에 유일한 번호 부여 (동점이라도 순위가 다름)

idnamesalaryrow_num
1Alice70001
2Bob60002
3Carol60003
4Dave50004

5. 이전/다음 행 값 가져오기 (LAG(), LEAD())

📌 1) LAG() (이전 행 값 가져오기)

SELECT id, name, salary, 
       LAG(salary, 1, 0) OVER (ORDER BY id) AS prev_salary
FROM employees;

✔ 현재 행에서 이전 행의 salary 가져오기 (없으면 0)

idnamesalaryprev_salary
1Alice50000
2Bob60005000
3Carol70006000

📌 2) LEAD() (다음 행 값 가져오기)

SELECT id, name, salary, 
       LEAD(salary, 1, 0) OVER (ORDER BY id) AS next_salary
FROM employees;

✔ 현재 행에서 다음 행의 salary 가져오기 (없으면 0)

idnamesalarynext_salary
1Alice50006000
2Bob60007000
3Carol70000

6. 백분율 및 그룹 나누기

📌 1) PERCENT_RANK() (비율 순위)

SELECT id, name, salary, 
       PERCENT_RANK() OVER (ORDER BY salary DESC) AS percentile_rank
FROM employees;

전체 데이터에서 현재 값이 몇 % 위치인지 반환 (0 ~ 1 사이 값)


📌 2) CUME_DIST() (누적 비율)

SELECT id, name, salary, 
       CUME_DIST() OVER (ORDER BY salary DESC) AS cumulative_distribution
FROM employees;

현재 값까지의 누적 비율(누적 개수 / 전체 개수) 계산


📌 3) NTILE(n) (그룹 나누기)

SELECT id, name, salary, 
       NTILE(3) OVER (ORDER BY salary DESC) AS group_num
FROM employees;

데이터를 n개의 그룹으로 나눔 (예: 3등분)


🔥 정리

함수설명
SUM(), AVG(), COUNT()그룹 없이 개별 행 유지하며 집계
RANK(), DENSE_RANK(), ROW_NUMBER()순위 매기기
LAG(), LEAD()이전/다음 행 값 참조
PERCENT_RANK(), CUME_DIST()백분율 순위 계산
NTILE(n)데이터를 n개의 그룹으로 나누기

0개의 댓글