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을 더 강력하게 만들어주는 중요한 기능입니다.
이해가 어렵다면 직접 실행해보면서 익혀보세요! 🚀
'개발 > SQL' 카테고리의 다른 글
CASE 문으로 데이터 변환: 동적 값 변환과 그룹핑 (4) | 2025.03.20 |
---|---|
LEAD & LAG 함수 사용법: 이전/다음 행 참조하기 (2) | 2025.03.19 |
서브쿼리(Subquery) 활용법: EXISTS, IN, ANY, ALL (6) | 2025.03.17 |
JOIN 종류 정리: INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN 비교 (0) | 2025.03.16 |
HAVING과 WHERE 차이: 그룹 함수와 함께 쓰이는 HAVING의 활용 (0) | 2025.03.15 |