📌 윈도우 함수(Window Function)란?
윈도우 함수는 행을 그룹화하지 않고 각 행에 대해 특정 범위(윈도우) 내에서 계산을 수행하는 SQL 함수.
즉, GROUP BY처럼 데이터를 하나로 합치지 않고도 집계 함수(Aggregate Function) + 추가적인 행 정보를 같이 조회할 수 있다.
📌 윈도우 함수의 기본 구조
<윈도우 함수>(<집계 대상>) OVER (
PARTITION BY <그룹 기준>
ORDER BY <정렬 기준>
ROWS BETWEEN <윈도우 크기>
)
✔️ 핵심 요소
- 윈도우 함수 → SUM(), AVG(), RANK() 등 사용 가능
- OVER() → 윈도우 함수를 사용할 때 필수
- PARTITION BY → 그룹을 나누는 기준 (선택)
- ORDER BY → 정렬 기준 (선택)
- ROWS BETWEEN → 계산 범위 지정 (선택)
🏆 윈도우 함수 종류
✅ 1. 순위 함수 (Ranking Functions)
함수 | 설명 |
RANK() | 동점자가 있을 경우 같은 순위를 부여하고, 다음 순위를 건너뜀 (ex. 1, 2, 2, 4) |
DENSE_RANK() | 동점자가 있어도 연속적인 순위를 부여 (ex. 1, 2, 2, 3) |
ROW_NUMBER() | 순위를 매기되, 동점자가 있어도 고유한 번호를 부여 (ex. 1, 2, 3, 4) |
SELECT EMP_NO, EMP_NAME, SALARY,
RANK() OVER (ORDER BY SALARY DESC) AS RANKING,
DENSE_RANK() OVER (ORDER BY SALARY DESC) AS DENSE_RANKING,
ROW_NUMBER() OVER (ORDER BY SALARY DESC) AS ROW_NUM
FROM HR_EMPLOYEES;
✅ 2. 집계 함수 (Aggregate Functions)
함수 | 설명 |
SUM() | 현재 행을 포함하여 누적 합계 계산 |
AVG() | 현재 행을 포함하여 평균 계산 |
MIN() / MAX() | 그룹 내 최소/최대값 계산 |
COUNT() | 그룹 내 행 개수 계산 |
SELECT EMP_NO, EMP_NAME, DEPT, SALARY,
SUM(SALARY) OVER (PARTITION BY DEPT) AS DEPT_TOTAL_SALARY,
AVG(SALARY) OVER (PARTITION BY DEPT) AS DEPT_AVG_SALARY
FROM HR_EMPLOYEES;
💡 부서별(PARTITION BY DEPT) 총급여와 평균급여를 구할 수 있다
✅ 3. 이동 평균 및 누적 합 (Window Frame)
함수 | 설명 |
LAG() | 이전 행의 값을 가져옴 |
LEAD() | 다음 행의 값을 가져옴 |
FIRST_VALUE() | 그룹 내 첫 번째 값 반환 |
LAST_VALUE() | 그룹 내 마지막 값 반환 |
SELECT EMP_NO, EMP_NAME, SALARY,
LAG(SALARY, 1) OVER (ORDER BY SALARY DESC) AS PREV_SALARY,
LEAD(SALARY, 1) OVER (ORDER BY SALARY DESC) AS NEXT_SALARY
FROM HR_EMPLOYEES;
💡 각 직원의 이전 연봉과 다음 연봉을 확인할 수 있다
🔹 LAG(SALARY, 1) → 현재 행보다 1행 이전의 값을 가져옴
🔹 LEAD(SALARY, 1) → 현재 행보다 1행 이후의 값을 가져옴
🔹 LAG(SALARY) → 기본값이 1이므로 LAG(SALARY, 1)과 동일함
🔹 즉, 명시적으로 1을 적지 않아도 기본적으로 1행 이전 값을 가져옴
🔹 만약 LAG(SALARY, 2)라고 하면 2행 이전 값을 가져오게 됨
🔥 윈도우 함수 vs GROUP BY 차이
기준 | 윈도우 함수 | GROUP BY |
행 개수 유지 | ✅ 유지됨 | ❌ 그룹별 1개 행만 남음 |
추가적인 정보 제공 | ✅ 개별 행의 정보와 집계 값 함께 표시 가능 | ❌ 오직 집계 값만 표시 |
사용 가능 함수 | SUM(), AVG(), RANK(), LAG(), LEAD() 등 | SUM(), AVG(), COUNT() 등 |
🔴 GROUP BY
-- GROUP BY 사용
SELECT DEPT, SUM(SALARY) AS TOTAL_SALARY
FROM HR_EMPLOYEES
GROUP BY DEPT;
-> GROUP BY를 사용하면 개별 직원 정보가 사라지고 부서별 총급여만 남는다.
DEPT | TOTAL_SALARY |
HR | 150,000 |
Sales | 200,000 |
IT | 250,000 |
🟢 윈도우 함수
-- 윈도우 함수 사용
SELECT EMP_NO, EMP_NAME, DEPT, SALARY,
SUM(SALARY) OVER (PARTITION BY DEPT) AS DEPT_TOTAL_SALARY
FROM HR_EMPLOYEES;
-> 윈도우 함수를 사용하면 개별 직원 정보는 그대로 유지하면서 부서별 총급여도 함께 조회 가능
EMP_NO | EMP_NAME | DEPT | SALARY | DEPT_TOTAL_SALARY |
101 | Alice | HR | 50,000 | 150,000 |
102 | Bob | HR | 60,000 | 150,000 |
103 | Charlie | HR | 40,000 | 150,000 |
201 | David | Sales | 80,000 | 200,000 |
202 | Eva | Sales | 70,000 | 200,000 |
203 | Frank | Sales | 50,000 | 200,000 |
301 | Grace | IT | 90,000 | 250,000 |
302 | Henry | IT | 85,000 | 250,000 |
303 | Irene | IT | 75,000 | 250,000 |
🎯 윈도우 함수 활용 예제
1. RANK()를 활용한 직원별 연봉 순위
SELECT EMP_NO, EMP_NAME, SALARY,
RANK() OVER (ORDER BY SALARY DESC) AS SALARY_RANK
FROM HR_EMPLOYEES;
2. SUM()을 활용한 누적 합계
SELECT EMP_NO, EMP_NAME, SALARY,
SUM(SALARY) OVER (ORDER BY EMP_NO) AS CUMULATIVE_SALARY
FROM HR_EMPLOYEES;
3. LAG()를 활용한 전월 대비 급여 비교
SELECT EMP_NO, EMP_NAME, SALARY,
LAG(SALARY) OVER (PARTITION BY DEPT ORDER BY EMP_NO) AS PREV_MONTH_SALARY
FROM HR_EMPLOYEES;
✅ 정리
- 윈도우 함수는 GROUP BY처럼 데이터를 그룹화하지 않고도 개별 행을 유지하면서 집계 가능
- RANK(), DENSE_RANK(), ROW_NUMBER() 등 순위 함수 활용 가능
- SUM(), AVG(), LAG(), LEAD() 등을 통해 누적 합산, 이동 평균, 비교 분석 가능
- GROUP BY와 달리 개별 행을 포함한 상태에서 그룹 내 연산을 수행할 수 있음
'SQL' 카테고리의 다른 글
WITH 절 (CTE, Common Table Expression) + RECURSIVE 재귀문 (0) | 2024.08.06 |
---|---|
SQL 데이터 추가 / 삭제/ 수정 (2) | 2024.07.20 |
[MySQL] Pivot Table 만들기 (0) | 2024.06.25 |
REGEXP(Regular Expression) 정규 표현식 (0) | 2024.06.24 |
SQL 기본문법 (0) | 2024.06.05 |