지난 강의에서 윈도우 함수가 왜 필요한지 알았지? 이제 실제 함수들이 어떻게 동작하는지랑 결과를 볼 거야. 문법 디테일은 다음 강의에서 다룰 거니까 지금은 감만 잡자.
ROW_NUMBER() 함수
ROW_NUMBER() 함수는 윈도우 안에서 각 행마다 유니크한 번호를 붙여줘. 그냥 ORDER BY로 정렬된 순서대로 번호가 매겨지는 거지.
문법:
ROW_NUMBER() OVER ([PARTITION BY column] ORDER BY column)
여기서:
PARTITION BY column(옵션): 데이터를 그룹으로 나눠. 생략하면 전체 데이터셋에 대해 번호가 매겨져.ORDER BY column: 번호 매길 때 행의 순서를 정해줘.
예시. 테이블 행에 번호 붙이기
students 테이블을 보자. 학생들이랑 점수 정보가 들어있어.
SELECT * FROM students;
| id | name | score |
|---|---|---|
| 1 | Eva Lang | 95 |
| 2 | Maria Chi | 87 |
| 3 | Alex Lin | 78 |
| 4 | Anna Song | 95 |
| 5 | Otto Mart | 87 |
이제 점수(score) 내림차순으로 행에 번호를 붙여보자:
SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;
결과:
| name | score | row_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 2 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 4 |
| Alex Lin | 78 | 5 |
각 행마다 점수 내림차순 기준으로 유니크한 번호가 붙었지.
이렇게 쿼리 결과에 행 번호를 붙이는 건 진짜 간단하지만 강력해. 일반 SELECT만으로는 윈도우 함수 없이 이걸 못해.
RANK() 함수
RANK() 함수는 ROW_NUMBER()랑 비슷한데, 동일한 값이 있으면 같은 랭크를 줘. 그리고 다음 랭크는 건너뛰어.
문법:
RANK() OVER ([PARTITION BY column] ORDER BY column)
예시. 학생 점수 랭킹 매기기
아까랑 똑같은 데이터로 RANK()를 써보자:
SELECT
name,
score,
RANK() OVER (ORDER BY score DESC) AS rank
FROM students;
결과:
| name | score | rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 3 |
| Alex Lin | 78 | 5 |
여기서 95랑 87처럼 같은 점수는 같은 랭크를 받고, 그 다음 랭크는 건너뛰는 거 보여?
DENSE_RANK() 함수
DENSE_RANK()는 RANK()랑 비슷한데, 랭크 값이 건너뛰지 않아. 즉, 중복된 행이 있어도 다음 랭크는 바로 +1이야.
문법:
DENSE_RANK() OVER ([PARTITION BY column] ORDER BY column)
예시. 촘촘한 랭킹
똑같은 데이터로 DENSE_RANK()를 써보자:
SELECT
name,
score,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;
결과:
| name | score | dense_rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
RANK()랑 다르게 랭크 값이 건너뛰지 않고 바로 이어져.
NTILE() 함수
NTILE() 함수는 행을 똑같은 크기의 그룹(분위수)으로 나누고, 각 행에 그룹 번호를 붙여줘.
문법:
NTILE(n) OVER ([PARTITION BY column] ORDER BY column)
n: 데이터를 나눌 그룹 개수야.
예시. 학생을 3개 그룹으로 나누기
학생들을 점수 내림차순으로 3개 그룹으로 나눠보자:
SELECT
name,
score,
NTILE(3) OVER (ORDER BY score DESC) AS group_num
FROM students;
결과:
| name | score | group_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
참고로, 행을 완전히 똑같이 나눌 수 없으면 남는 행은 앞쪽 그룹에 들어가. 여기선 앞의 두 그룹이 2개씩, 마지막 그룹이 1개야.
언제 어떤 함수를 써야 할까?
ROW_NUMBER(): 정렬 순서대로 행에 유니크한 번호 붙이고 싶을 때.RANK(): 같은 값이 있으면 같은 랭크 주고, 다음 랭크는 건너뛰고 싶을 때.DENSE_RANK(): 같은 값이 있어도 랭크 값이 건너뛰지 않게 하고 싶을 때.NTILE(): 행을 균등하게 그룹으로 나누고 싶을 때.
이 함수들만 잘 써도 데이터 분석이 한 단계 업그레이드 돼. 순위 매기거나 그룹 나눌 때 윈도우 함수로 유연하게 처리해보자!
GO TO FULL VERSION