SQL : Top N Query

Skele·2025년 5월 21일

SQL

목록 보기
7/11
post-thumbnail

Top N Query

TOP N 쿼리는 정렬된 결과에서 특정 개수(N)의 최상위 행을 추출하는 기법이다. 페이징 처리나 순위 기반 조회 시 효과적으로 사용할 수 있다.

구현 방법

방법설명지원 DBMS예시
ROWNUM오라클에서 각 행에 번호를 부여하는 가상 컬럼OracleSELECT * FROM (SELECT * FROM EMP ORDER BY SAL DESC) WHERE ROWNUM <= 5;
FETCHANSI 표준 SQL:2008부터 도입된 방식Oracle 12c 이상, PostgreSQLSELECT * FROM EMP ORDER BY SAL DESC FETCH FIRST 5 ROWS ONLY;
TOPSQL Server에서 제공하는 TOP N 구문SQL ServerSELECT TOP 5 * FROM EMP ORDER BY SAL DESC;
LIMITMySQL, PostgreSQL 등에서 사용하는 방식MySQL, PostgreSQLSELECT * FROM EMP ORDER BY SAL DESC LIMIT 5;

ROWNUM을 이용한 TOP N 쿼리

ROWNUM은 Oracle에서 제공하는 가상 컬럼으로, 쿼리 결과의 각 행에 1부터 시작하는 번호를 부여한다.

-- 급여가 높은 순서로 상위 5명의 직원 정보 출력 (올바른 방법)
SELECT *
FROM (SELECT EMPNO, ENAME, SAL
      FROM EMP
      ORDER BY SAL DESC)
WHERE ROWNUM <= 5;

서브쿼리에서 먼저 정렬한 후 바깥 쿼리에서 ROWNUM 조건을 적용한다.

실행 결과

실제 급여 상위 5명:

EMPNOENAMESAL
7839KING5000
7788SCOTT3000
7902FORD3000
7566JONES2975
7698BLAKE2850

주의사항

  • ROWNUM은 WHERE 절에서 행이 선택될 때 할당된다.
  • "ROWNUM > n" 조건은 직접 사용할 수 없다(이미 n보다 큰 번호가 할당되지 않았기 때문).
  • 정렬된 결과에서 TOP N을 추출하려면 서브쿼리를 사용해야 한다.
-- 급여가 높은 순서로 상위 5명의 직원 정보 출력 (잘못된 방법)
SELECT EMPNO, ENAME, SAL, ROWNUM
FROM EMP
WHERE ROWNUM <= 5
ORDER BY SAL DESC;

위 쿼리의 문제점은 먼저 ROWNUM 조건으로 5개 행을 선택한 후 정렬하기 때문에, 실제 급여 상위 5명이 아닌 임의의 5명이 선택된다.

실행 결과

임의의 5명이 선택되고 그 중에서 급여 순으로 정렬됨:

EMPNOENAMESALROWNUM
7839KING50003
7566JONES29752
7782CLARK24504
7369SMITH8001
7876ADAMS11005

페이징 처리

특정 범위의 행을 추출할 때(예: 4~6번째 행), 단일 ROWNUM 조건으로는 불가능하다. 이때는 중첩 서브쿼리를 사용한다.

-- 급여가 높은 순서로 4~6번째 직원 정보 출력
SELECT *
FROM (SELECT EMPNO, ENAME, SAL, ROWNUM AS RN
      FROM (SELECT EMPNO, ENAME, SAL
            FROM EMP
            ORDER BY SAL DESC))
WHERE RN BETWEEN 4 AND 6;
  1. 가장 안쪽 서브쿼리: 급여 내림차순으로 정렬
  2. 중간 서브쿼리: ROWNUM 할당하여 RN이라는 별칭 부여
  3. 바깥 쿼리: RN 값으로 범위 지정
실행 결과

급여 순위 4~6위:

EMPNOENAMESALRN
7566JONES29754
7698BLAKE28505
7782CLARK24506

FETCH 절

Oracle 12c 이상에서는 ANSI 표준 SQL의 FETCH 절을 사용할 수 있다.

-- 급여가 높은 순서로 상위 5명의 직원 정보 출력
SELECT EMPNO, ENAME, SAL
FROM EMP
ORDER BY SAL DESC
FETCH FIRST 5 ROWS ONLY;
실행 결과

급여 상위 5명:

EMPNOENAMESAL
7839KING5000
7788SCOTT3000
7902FORD3000
7566JONES2975
7698BLAKE2850
-- OFFSET과 함께 사용하여 페이징 처리
SELECT EMPNO, ENAME, SAL
FROM EMP
ORDER BY SAL DESC
OFFSET 3 ROWS         -- 처음 3행 건너뜀
FETCH NEXT 3 ROWS ONLY; -- 다음 3행 추출
실행 결과

급여 순위 4~6위:

EMPNOENAMESAL
7566JONES2975
7698BLAKE2850
7782CLARK2450

FETCH 절의 장점은 OFFSET과 함께 사용하여 간결하게 페이징 처리를 할 수 있다는 점이다.

SQL Server의 TOP 절

SQL Server에서는 TOP 절을 사용하여 쉽게 상위 N개 행을 추출할 수 있다.

-- 급여가 높은 순서로 상위 5명의 직원 정보 출력
SELECT TOP 5 EMPNO, ENAME, SAL
FROM EMP
ORDER BY SAL DESC;
실행 결과

급여 상위 5명:

EMPNOENAMESAL
7839KING5000
7788SCOTT3000
7902FORD3000
7566JONES2975
7698BLAKE2850
-- 동일한 값이 있을 경우 함께 반환 (WITH TIES)
SELECT TOP 5 WITH TIES EMPNO, ENAME, SAL
FROM EMP
ORDER BY SAL DESC;
실행 결과

SCOTT와 FORD가 같은 급여로 공동 2위이므로 6명 출력:

EMPNOENAMESAL
7839KING5000
7788SCOTT3000
7902FORD3000
7566JONES2975
7698BLAKE2850
7782CLARK2450

WITH TIES 옵션을 사용하면 ORDER BY 절에 지정된 컬럼의 값이 같을 경우 모두 함께 반환한다.

profile
Tireless And Restless Debugging In Source : TARDIS

0개의 댓글