개발/SQL

윈도우 함수(Window Function) 기초: RANK(), DENSE_RANK(), ROW_NUMBER()

예니03 2025. 3. 18. 10:49
반응형

SQL에서 윈도우 함수(Window Function)전체 데이터 집합에서 특정 그룹(윈도우) 내에서 순위를 매기거나 누적 값을 계산하는 데 유용한 함수입니다.

특히, RANK(), DENSE_RANK(), ROW_NUMBER()는 순위를 매길 때 자주 사용되는 함수로,
이들의 차이를 이해하면 더 효율적인 SQL 쿼리를 작성할 수 있습니다.

이번 글에서는 윈도우 함수의 개념과 함께, RANK(), DENSE_RANK(), ROW_NUMBER()의 차이를 예제와 함께 쉽게 설명해드리겠습니다! 😊

 

🔹 1. 윈도우 함수(Window Function)란?

📌 윈도우 함수(Window Function)란, 전체 결과 집합을 기준으로 특정 그룹(윈도우, Window) 내에서 연산을 수행하는 함수입니다.
✔ GROUP BY와 달리 집계 함수(Aggregate Function)처럼 데이터를 줄이지 않고, 각 행마다 값을 계산할 수 있는 것이 특징입니다.

윈도우 함수 기본 문법

윈도우_함수() OVER (
    PARTITION BY 그룹기준컬럼
    ORDER BY 정렬기준컬럼
)

✔ PARTITION BY: 특정 그룹별로 윈도우를 나눔 (생략 가능)
✔ ORDER BY: 정렬 기준 지정 (순위 매길 때 필수)

 

🔹 2. 윈도우 함수의 대표적인 순위 함수 3가지

1️⃣ RANK() – 동일 순위 발생 시 건너뛰는 순위

📌 RANK() 함수는 동일한 값에 대해 같은 순위를 부여하며, 중복된 순위 개수만큼 다음 순위를 건너뜁니다.

2️⃣ DENSE_RANK() – 동일 순위 발생해도 다음 순위 연속 유지

📌 DENSE_RANK()는 동일한 값에 대해 같은 순위를 부여하지만, 다음 순위를 건너뛰지 않습니다.

3️⃣ ROW_NUMBER() – 동일 값 상관없이 일렬 순위 부여

📌 ROW_NUMBER()는 동일한 값이 있어도 무조건 고유한 순위를 부여합니다.

 

🔹 3. 예제 테이블 & 데이터 생성

다음과 같은 사원 급여 정보 테이블(employees)을 사용하여 실습해보겠습니다.

🔸 employees (직원 테이블)

emp_id name department salary
1 Alice IT 5000
2 Bob IT 6000
3 Charlie IT 6000
4 David HR 7000
5 Emma HR 7000
6 Frank HR 6500

 

🔹 4. RANK(), DENSE_RANK(), ROW_NUMBER() 비교

📌 IT 부서 직원들의 급여 순위를 매겨보겠습니다!

SELECT 
    name, 
    salary,
    RANK() OVER (ORDER BY salary DESC) AS rank_value,
    DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank_value,
    ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_number_value
FROM employees
WHERE department = 'IT';

🔹 결과 (IT 부서 직원 급여 순위 비교)

name salary RANK() DENSE_RANK() ROW_NUMBER()
Bob 6000 1 1 1
Charlie 6000 1 1 2
Alice 5000 3 2 3

✔ RANK(): 동일한 급여는 같은 순위, 건너뜀 (1, 1, 3)
✔ DENSE_RANK(): 동일한 급여는 같은 순위, 건너뛰지 않음 (1, 1, 2)
✔ ROW_NUMBER(): 무조건 연속적인 순위 (1, 2, 3)

 

🔹 5. PARTITION BY를 사용한 그룹별 순위 계산

📌 부서별(department) 급여 순위를 구해보겠습니다!

SELECT 
    name, 
    department,
    salary,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_value
FROM employees;

🔹 결과 (부서별 급여 순위)

name department salary RANK()
Bob IT 6000 1
Charlie IT 6000 1
Alice IT 5000 3
David HR 7000 1
Emma HR 7000 1
Frank HR 6500 3

✔ PARTITION BY department: 부서별(Window)로 나누어서 순위 부여
같은 급여는 같은 순위(RANK 사용 시)

 

🔹 6. RANK() vs. DENSE_RANK() vs. ROW_NUMBER() 요약 정리

함수 동일 값 처리 방식 순위 건너뜀 여부 고유 순위 여부
RANK() 동일 값이면 같은 순위 건너뜀 (순위 중복 개수만큼)
DENSE_RANK() 동일 값이면 같은 순위 건너뛰지 않음
ROW_NUMBER() 동일 값이라도 각 행에 고유한 순위 부여 없음

 

🔹 7. 언제 어떤 순위 함수를 사용해야 할까?

등수(순위)만 알고 싶다면? → RANK()
연속된 순위를 유지하고 싶다면? → DENSE_RANK()
각 행에 고유한 번호를 부여하고 싶다면? → ROW_NUMBER()

 

🔹 8. 실전 연습 문제

다음 SQL을 작성해보세요!

1️⃣ 부서별(department) 급여 순위를 DENSE_RANK()로 구하기
2️⃣ 전체 직원 중에서 ROW_NUMBER()를 사용하여 순번 매기기
3️⃣ 급여가 높은 순서대로 RANK()를 사용해 직원 순위 구하기

정답을 댓글로 남겨주세요! 😊✨

👉 윈도우 함수는 SQL을 더 강력하게 만들어주는 중요한 기능입니다.
이해가 어렵다면 직접 실행해보면서 익혀보세요! 🚀

반응형