오라클을 다루다 보면 데이터의 순위를 매기거나 특정 그룹 내에서 개수를 세야 할 때가 많습니다. 이때 ROW_NUMBER() 함수와 COUNT() OVER 함수가 유용합니다. 오늘은 이 두 함수를 설명하고 어떻게 활용할 수 있는지 예제와 함께 알아보겠습니다.
1. ROW_NUMBER() 함수란?
ROW_NUMBER() 함수는 정렬된 결과 집합에서 각 행에 고유한 **순번(번호)**을 부여하는 윈도우 함수(Window Function)입니다. 단순히 ROWNUM을 사용하는 것과 달리, 원하는 기준에 따라 순위를 지정할 수 있다는 장점이 있습니다.
기본 문법
SELECT 컬럼명, ROW_NUMBER() OVER (PARTITION BY 그룹컬럼 ORDER BY 정렬컬럼) AS 순번
FROM 테이블명;
주요 개념
- OVER() : 윈도우 함수의 범위를 지정하는 역할
- PARTITION BY 그룹컬럼 : 그룹을 나누는 기준 (생략 가능)
- ORDER BY 정렬컬럼 : 순번을 부여할 정렬 기준
예제: 각 부서별(Employee 테이블) 급여 순위 구하기
SELECT EMPLOYEE_ID, DEPARTMENT_ID, SALARY,
ROW_NUMBER() OVER (PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC) AS RANK
FROM EMPLOYEES;
결과 예시:
EMPLOYEE_ID | DEPARTMENT_ID | SALARY | RANK |
101 | 10 | 7000 | 1 |
102 | 10 | 6000 | 2 |
103 | 10 | 5000 | 3 |
201 | 20 | 8000 | 1 |
202 | 20 | 7500 | 2 |
PARTITION BY DEPARTMENT_ID를 사용하여 각 부서(DEPARTMENT_ID)별로 순위를 매겼습니다.
2. COUNT() OVER() 함수란?
COUNT() OVER() 함수는 그룹별 데이터 개수를 구할 때 사용하는 윈도우 함수입니다. 일반적인 COUNT() 함수와 달리, GROUP BY 없이도 전체 행을 유지하면서 특정 기준의 개수를 구할 수 있습니다.
기본 문법
SELECT 컬럼명, COUNT(*) OVER (PARTITION BY 그룹컬럼) AS 개수
FROM 테이블명;
예제: 각 부서별(Employee 테이블) 직원 수 구하기
SELECT EMPLOYEE_ID, DEPARTMENT_ID,
COUNT(*) OVER (PARTITION BY DEPARTMENT_ID) AS EMP_COUNT
FROM EMPLOYEES;
결과 예시:
EMPLOYEE_ID | DEPARTMENT_ID | EMP_COUNT |
101 | 10 | 3 |
102 | 10 | 3 |
103 | 10 | 3 |
201 | 20 | 2 |
202 | 20 | 2 |
PARTITION BY DEPARTMENT_ID를 사용하여 각 부서별 직원 수를 계산했으며, 모든 행에 직원 수가 그대로 표시됩니다.
3. ROW_NUMBER() vs COUNT() OVER() 비교
함수명 | 역할 | PARTITION BY 사용 시 효과 |
ROW_NUMBER() | 순위를 매김 | 각 그룹 내에서 개별적인 순번을 부여 |
COUNT() OVER() | 개수 계산 | 각 그룹 내 총 개수를 모든 행에 표시 |
둘을 함께 사용하면 특정 그룹에서 순위를 매기면서 개수도 확인할 수 있습니다.
예제: 부서별 급여 순위 & 직원 수 확인
SELECT EMPLOYEE_ID, DEPARTMENT_ID, SALARY,
ROW_NUMBER() OVER (PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC) AS RANK,
COUNT(*) OVER (PARTITION BY DEPARTMENT_ID) AS EMP_COUNT
FROM EMPLOYEES;
결과 예시:
EMPLOYEE_ID | DEPARTMENT_ID | SALARY | RANK | EMP_COUNT |
101 | 10 | 7000 | 1 | 3 |
102 | 10 | 6000 | 2 | 3 |
103 | 10 | 5000 | 3 | 3 |
201 | 20 | 8000 | 1 | 2 |
202 | 20 | 7500 | 2 | 2 |
이렇게 하면 부서별 급여 순위와 함께 부서 내 직원 수까지 한 번에 확인할 수 있습니다.
예제: 중복 데이터를 제거하고 하나의 대표 데이터만 표시하기
중복된 데이터를 제거하고 특정 기준에서 대표값 하나만 남기고 싶을 때 ROW_NUMBER()를 활용할 수 있습니다.
SELECT EMPLOYEE_ID, DEPARTMENT_ID, SALARY
FROM (
SELECT EMPLOYEE_ID, DEPARTMENT_ID, SALARY,
ROW_NUMBER() OVER (PARTITION BY DEPARTMENT_ID ORDER BY SALARY DESC) AS RID
FROM EMPLOYEES
) WHERE RID = 1;
결과 예시:
EMPLOYEE_ID | DEPARTMENT_ID | SALARY |
101 | 10 | 7000 |
201 | 20 | 8000 |
이렇게 하면 각 DEPARTMENT_ID 별로 가장 높은 급여를 받는 직원 한 명만 표시할 수 있습니다.
'Programming > DB' 카테고리의 다른 글
ORACLE ORA-01427: 단일 행 하위 질의에 2개 이상의 행이 리턴되었습니다 오류 해결 방법 (0) | 2025.04.07 |
---|---|
ORACLE ORA-01555: Snapshot Too Old 오류 해결 방법 (0) | 2025.04.05 |
ORACLE ORA-01652 오류: "임시 세그먼트를 확장할 수 없습니다" 해결 방법 (0) | 2025.04.04 |
ORACLE MERGE INTO와 UPDATE의 차이점 (1) | 2024.10.30 |
ORACLE 로또 번호 추출하기 - 로또 SQL (0) | 2022.01.25 |