TOP-N 쿼리 정리

TJK·2025년 8월 22일

TOP-N 쿼리 정리

TOP-N 쿼리는 결과 집합에서 상위 N개 또는 하위 N개의 행을 조회하는 기법입니다. SQLD 시험에서는 이 개념을 구현하는 다양한 방법(특히 ROWNUM, ROW_NUMBER, FETCH 등)과 각 방법의 특징을 명확히 구분하는 문제가 자주 출제됩니다.


1. 핵심 개념: ROWNUM vs 윈도우 함수 (★★★★★)

TOP-N 쿼리는 단순히 ORDER BY만으로는 구현할 수 없으며, 순위를 매기는 함수나 가상 컬럼을 활용해야 합니다.

구분ROWNUM (Oracle)ROW_NUMBER() (ANSI)RANK() (ANSI)DENSE_RANK() (ANSI)
개념쿼리 결과에 부여되는 가상 행 번호윈도우 함수로 순차적인 순위 부여동일 값에 같은 순위를 부여, 다음 순위 건너뜀동일 값에 같은 순위를 부여, 다음 순위 건너뛰지 않음
특징ORDER BY보다 먼저 처리되어 정렬 전의 순위가 매겨짐.ORDER BY 후 순위가 매겨져 정확한 순서를 부여.(1, 2, 2, 4)(1, 2, 2, 3)
주의점WHERE ROWNUM > N 조건으로 단독 사용 시 결과 없음.PARTITION BY와 함께 그룹별 순위 부여 가능.DENSE_RANK()와 차이점 구분.RANK()와 차이점 구분.

2. TOP-N 쿼리 구현 방법 (★★★★★)

1. ROWNUM을 활용한 TOP-N

ROWNUMORDER BY보다 먼저 실행되기 때문에, 먼저 정렬을 수행하는 인라인 뷰를 사용해야 원하는 결과를 얻을 수 있습니다.

SELECT employee_name, salary
FROM (
  SELECT employee_name, salary
  FROM employees
  ORDER BY salary DESC
) -- 정렬이 먼저 수행
WHERE ROWNUM <= 3; -- 정렬된 결과에 ROWNUM 부여

2. FETCH FIRST를 활용한 TOP-N (ANSI 표준)

ANSI SQL 2011 표준 문법으로, ORDER BY 절 뒤에 위치하여 직관적입니다.

SELECT employee_name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 3 ROWS ONLY;

3. RANK 윈도우 함수 활용

WHERE 절에 윈도우 함수를 직접 사용할 수 없으므로, 인라인 뷰나 **CTE(WITH 절)**를 사용해야 합니다.

SELECT employee_name, salary
FROM (
  SELECT employee_name, salary,
         RANK() OVER (ORDER BY salary DESC) as rnk
  FROM employees
)
WHERE rnk <= 3;

3. SQLD 시험 핵심 포인트

  • ROWNUM의 치명적 함정: WHERE ROWNUM > 1과 같은 조건은 논리적 오류로 인해 항상 FALSE가 되어 결과를 반환하지 않습니다. ROWNUM<=, < 조건에만 정상 작동합니다. (★★★★★)
  • 정렬의 중요성: ROWNUMORDER BY보다 먼저 실행됩니다. 따라서 ROWNUM을 사용하여 정확한 순위의 TOP-N을 얻으려면 반드시 ORDER BY가 포함된 서브쿼리를 사용해야 합니다.
  • RANK vs DENSE_RANK: 동점자가 있을 때 순위 건너뜀 여부를 묻는 문제가 자주 나옵니다. RANK는 다음 순위를 건너뛰고, DENSE_RANK는 건너뛰지 않습니다.

4. 최종 암기 팁 ✨

  • ROWNUM: **O**racle, **O**rder by **O**utside (정렬을 서브쿼리 안에서!)
  • FETCH: **F**irst **F**ew rows (몇 개만 가져와!)
  • RANK: 동점자를 **R**espect해서 다음 순위를 건너뜀.
  • DENSE_RANK: **D**ense (촘촘하게) 순위를 매겨서 건너뛰지 않음.

실전 기출 문제 스타일

1. 다음 쿼리의 실행 결과에 대한 설명으로 옳은 것은?

SELECT employee_name, salary
FROM employees
WHERE ROWNUM <= 3
ORDER BY salary DESC;

A. 연봉 순으로 상위 3명의 직원이 정확히 출력된다.
B. 정렬되지 않은 상태에서 3개 행이 선택된 후 정렬되므로, 연봉 순서와 맞지 않을 수 있다.
C. ROWNUM 조건으로 인해 구문 오류가 발생한다.
D. WHERE 조건이 ORDER BY보다 나중에 처리되어 의도한 결과를 얻을 수 있다.

2. ROWNUM > 3ROWNUM < 4 중 논리적으로 유효한 WHERE 조건은?
A. ROWNUM > 3
B. ROWNUM < 4
C. 둘 다 유효하다.
D. 둘 다 잘못된 조건이다.

3. 다음 중 연봉이 동일한 직원에게 같은 순위를 부여하고, 다음 순위를 건너뛰지 않는 함수는?
A. ROW_NUMBER()
B. RANK()
C. DENSE_RANK()
D. NTILE()


정답 및 해설

  • 문제 1 정답: B
    • 해설: ROWNUMWHERE 절보다 먼저 실행됩니다. 따라서 정렬되지 않은 상태에서 무작위로 3개의 행에 ROWNUM <= 3 조건이 적용되고, 그 후에 정렬되기 때문에 연봉 순서와 맞지 않을 수 있습니다.
  • 문제 2 정답: B
    • 해설: ROWNUM은 1부터 순차적으로 부여되므로 ROWNUM > 3 같은 조건은 첫 번째 행(ROWNUM=1)에서 실패하고, 다음 행에도 다시 ROWNUM=1이 부여되는 루프에 빠져 결과를 반환하지 않습니다. 반면 ROWNUM < 4는 첫 번째 행이 통과되어 ROWNUM=2가 부여되는 식으로 정상 동작합니다.
  • 문제 3 정답: C
    • 해설: DENSE_RANK()는 동점자에게 같은 순위를 부여하고, 다음 순위를 건너뛰지 않습니다(예: 1, 2, 2, 3). RANK()는 순위를 건너뜁니다(예: 1, 2, 2, 4). ROW_NUMBER()는 동일 순위를 허용하지 않고 연속된 번호를 부여합니다(예: 1, 2, 3, 4).
profile
Hello world!

0개의 댓글