Oracle의 ROW_NUMBER() OVER결과 집합의 각 행에 대해 정렬 기준을 기반으로 고유한 번호를 부여하는 윈도우 함수(Window Function) 입니다.

📌 기본 문법

ROW_NUMBER() OVER (PARTITION BY 컬럼명 ORDER BY 컬럼명)
  • ROW_NUMBER(): 각 행에 순차적인 번호를 부여하는 함수
  • PARTITION BY (선택 사항): 특정 그룹별로 행 번호를 부여 (예: 부서별 순위)
  • ORDER BY: 행 번호를 부여할 때 사용할 정렬 기준

1. 기본 사용법 (전체 데이터에 대해 순번 매기기)

ROW_NUMBER()를 사용하면 전체 데이터에서 정렬된 순서대로 행 번호를 부여할 수 있습니다.

직원 테이블에서 급여순으로 순번 매기기

SELECT employee_id, first_name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees;

🔹 ORDER BY salary DESC급여가 높은 순서대로 번호가 부여됩니다.

employee_idfirst_namesalaryrow_num
105Alice90001
204Bob85002
301Charlie80003
150David75004
220Eve70005

2. PARTITION BY 사용 (그룹별 순번 매기기)

특정 그룹(예: 부서별)로 나누어 각 그룹 내에서 별도의 행 번호를 부여하려면 PARTITION BY를 사용할 수 있습니다.

부서별(Department)로 나누어 급여순으로 순번 매기기

SELECT department_id, employee_id, first_name, salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num
FROM employees;

🔹 같은 department_id를 가진 직원들끼리 그룹을 나눈 후, 급여 내림차순으로 순번을 부여합니다.

department_idemployee_idfirst_namesalaryrow_num
10105Alice90001
10204Bob85002
20301Charlie80001
20150David75002
20220Eve70003

3. ROW_NUMBER()로 TOP N 쿼리 구현

ROW_NUMBER()를 활용하면 정렬된 데이터에서 특정 개수(N개)만 선택하는 TOP N 쿼리를 만들 수 있습니다.

급여가 가장 높은 상위 5명 조회

SELECT *
FROM (
SELECT employee_id, first_name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees
)
WHERE row_num <= 5;

🔹 서브쿼리를 사용하여 정렬된 순서로 번호를 부여한 후, row_num <= 5 조건을 사용하여 상위 5명만 조회합니다.

4. ROW_NUMBER()를 활용한 페이징 처리

ROW_NUMBER()페이징(Pagination) 쿼리를 만들 때 많이 사용됩니다.
예를 들어, 6번째부터 10번째까지의 데이터를 가져오려면 다음과 같이 구현할 수 있습니다.

페이징 처리 (6~10번째 행 조회)

SELECT *
FROM (
SELECT employee_id, first_name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees
)
WHERE row_num BETWEEN 6 AND 10;

🔹 row_num BETWEEN 6 AND 10을 사용하여 6번째부터 10번째까지의 행을 가져옵니다.

5. ROW_NUMBER() vs RANK() vs DENSE_RANK() 차이점

함수역할중복 값 처리예제 결과
ROW_NUMBER()순차적인 번호 부여중복 값이 있어도 고유한 번호 부여1, 2, 3, 4, 5
RANK()순위를 매김 (동점자는 동일 순위)동일 값이면 동일 순위를 부여하지만, 다음 순위는 건너뜀1, 1, 3, 4, 5
DENSE_RANK()RANK()와 비슷하지만 순위를 건너뛰지 않음동일 값이면 동일 순위 부여, 다음 순위를 연속적으로 부여1, 1, 2, 3, 4

세 가지 함수 비교 예제

SELECT employee_id, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num,
RANK() OVER (ORDER BY salary DESC) AS rank_num,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank_num
FROM employees;
employee_idsalaryROW_NUMBER()RANK()DENSE_RANK()
1059000111
2049000211
3018500332
1508000443
2208000543
  • ROW_NUMBER(): 고유한 번호 부여 (1, 2, 3, 4, 5)
  • RANK(): 같은 값이면 같은 순위, 다음 순위 건너뜀 (1, 1, 3, 4, 4)
  • DENSE_RANK(): 같은 값이면 같은 순위, 순위 건너뛰지 않음 (1, 1, 2, 3, 3)

✅ 정리

  • ROW_NUMBER()고유한 번호를 부여할 때 사용
  • PARTITION BY그룹별 행 번호 부여
  • ROW_NUMBER()를 활용하면 TOP N 쿼리 및 페이징 처리 가능
  • 동점 순위를 고려하려면 RANK() 또는 DENSE_RANK() 사용

ROW_NUMBER()OVER 없이 사용할 수 있을까?

ROW_NUMBER() 함수는 반드시 OVER 절과 함께 사용해야 합니다.
OVER 없이 사용하면 오류(Error) 가 발생합니다.

📌 이유: ROW_NUMBER()는 윈도우 함수(Window Function)이기 때문

  • ROW_NUMBER()윈도우 함수(Window Function) 이므로, 윈도우(창, 범위) 를 지정해야 합니다.
  • OVER 절을 사용하여 정렬 기준(ORDER BY) 또는 그룹화(PARTITION BY) 를 지정해야 합니다.

잘못된 예제 (OVER 없이 사용)

SELECT employee_id, first_name, salary, ROW_NUMBER() AS row_num
FROM employees;

🚨 오류 발생:

ORA-30482: “WINDOW” 또는 “OVER” 절이 누락됨

🔹 ROW_NUMBER()개별 행에 단순히 번호를 부여하는 함수가 아니기 때문에 오류가 발생합니다.

✅ 올바른 사용법: OVER를 반드시 포함

1️⃣ 기본 사용법 (ORDER BY 필수)

SELECT employee_id, first_name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees;

🔹 ORDER BY salary DESC로 급여가 높은 직원부터 순차적인 번호(row_num)를 부여합니다.

2️⃣ 그룹별로 행 번호 매기기 (PARTITION BY)

SELECT department_id, employee_id, first_name, salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num
FROM employees;

🔹 부서별(department_id)로 나누어(PARTITION BY), 급여가 높은 순서대로 행 번호(row_num)를 부여합니다.

department_idemployee_idfirst_namesalaryrow_num
10105Alice90001
10204Bob85002
20301Charlie80001
20150David75002

🚀 결론

  • ROW_NUMBER()는 반드시 OVER 절과 함께 사용해야 합니다.
  • OVER 절에는 반드시 ORDER BY가 필요합니다.
  • PARTITION BY를 사용하면 그룹별로 행 번호를 부여할 수 있습니다.

💡 즉, OVER 없이 ROW_NUMBER()를 사용하면 오류가 발생하므로, 항상 OVER를 함께 사용하세요! ✅

zerg96

Recent Posts

노트북(윈도우)에서 아이폰 유선 테더링 하기

윈도우 운영체제의 노트북에서는 iPhone 유선 테더링이 잘 안되는 경우가 많습니다. 보통 iPhone의 드라이버가 설치가 안되있어서인…

3일 ago

오라클 래치(Latch)

오라클 데이터베이스의 성능을 논할 때, 내부적으로 발생하는 경합(Contention)은 피할 수 없는 주제다. 특히 다수의 프로세스가…

7일 ago

사장님도 3표, 나도 3표? ‘3%룰’ 완전 정복!

안녕하세요, 혹시 이런 생각해 본 적 없으신가요? "내가 투자한 회사는 누가 감시하고, 어떻게 운영될까?" 오늘은…

3주 ago

Vector Store(벡터 스토어)

'벡터 스토어' 완벽 가이드: AI 시대, 데이터의 새로운 심장을 만나다 IT 업계는 인공지능(AI)이라는 거대한 패러다임의…

3주 ago

Gemini CLI (재미나이 CLI)

1. Gemini CLI란 무엇인가요? Gemini CLI는 터미널 환경에서 직접 Gemini 모델과 상호작용할 수 있도록 만들어진…

3주 ago

과적합 (overfitting)

과적합은 머신러닝에서 학습용데이터를 과하게 학습하여, 실제데이터를 예측하지 못하는 현상을 말합니다. 인공지능(AI)의 학습 방법은 우리가 시험공부를…

1개월 ago