PostgreSQL PARTITION BY 와 ROW_NUMBER()

2025-06-21


사진: Unsplash 의 Marek Piwnicki

 


 

1. 기본 문법

 

ROW_NUMBER() OVER (PARTITION BY 컬럼1 [, 컬럼2, ...] ORDER BY 정렬기준)
  • PARTITION BY: 데이터를 그룹화할 기준 컬럼입니다. 이 컬럼 기준으로 각각 독립된 그룹처럼 계산됩니다.
  • ORDER BY: 각 그룹 내에서 순번을 매기는 정렬 기준입니다.

2. 예제

다음은 직원들의 부서별 입사일 순으로 순위를 부여하는 예제입니다.

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name TEXT,
    department TEXT,
    hired_date DATE
);

INSERT INTO employees (name, department, hired_date) VALUES
('철수', '개발팀', '2020-01-01'),
('영희', '개발팀', '2021-01-01'),
('민수', '디자인팀', '2019-03-01'),
('수지', '디자인팀', '2020-06-01'),
('준호', '개발팀', '2019-07-01');

SELECT 
    id,
    name,
    department,
    hired_date,
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY hired_date) AS rank_in_department
FROM 
    employees;

3. 결과

ID NAME DEPARTMENT HIRED_DATE RANK_IN_DEPARTMENT
5 준호 개발팀 2019-07-01 1
1 철수 개발팀 2020-01-01 2
2 영희 개발팀 2021-01-01 3
3 민수 디자인팀 2019-03-01 1
4 수지 디자인팀 2020-06-01 2

 

  • 각 customer_id 별로 주문 날짜 내림차순 정렬
  • ROW_NUMBER()를 사용하여 1번(최신)만 추출

 


4. 주의 사항

  • ROW_NUMBER()는 같은 값이 있어도 순번이 강제로 다르게 부여됩니다. (동점 없음)
  • 동점 순위 처리를 원하면 RANK() 또는 DENSE_RANK()를 사용하세요.
  • PARTITION BY가 없는 경우 전체 테이블을 하나의 그룹으로 간주합니다.

5. 정리

함수특징

 

ROW_NUMBER() 순서대로 1,2,3,… 부여 (동점 없음)
RANK() 동점 있을 경우 같은 순위, 다음 순위 건너뜀
DENSE_RANK() 동점 있어도 순위 건너뛰지 않음

메인 이미지 출처 : 사진: UnsplashMarek Piwnicki