핵심 요약
다중 정렬 기준·NULL 배치·ROW_NUMBER와 FETCH를 이용한 안정적인 Top-N을 이해한다.
학습 목표
- ASC·
DESC와 NULL 정렬 위치를 명시한다. - Top-N과 페이지 조회에 결정적인 정렬 기준이 필요한 이유를 설명한다.
본문
개념 지도
결과 행 생성→정렬 기준·방향·NULL 위치→동점 Tie-breaker→행 제한핵심 내용
관계형 결과는 ORDER BY가 없으면 순서가 보장되지 않는다. 여러 기준을 왼쪽부터 적용하며 각 기준마다 ASC·
SELECT empno, ename, sal
FROM emp
ORDER BY sal DESC, empno ASC;
동점이 존재할 수 있는 sal만 정렬하면 실행마다 동점 행 순서가 달라질 수 있다. PK 같은 유일한 컬럼을 마지막 정렬 기준으로 추가하면 안정적이다. Oracle은 NULLS FIRST, NULLS LAST로 NULL 위치를 명시할 수 있다.
상위 N건은 최신 문법의 FETCH FIRST 또는 분석 함수로 표현한다.
SELECT empno, sal
FROM emp
ORDER BY sal DESC, empno
FETCH FIRST 5 ROWS ONLY;
ROWNUM을 사용한다면 정렬보다 먼저 부여될 수 있으므로 정렬한 인라인 뷰 바깥에서 제한하는 구조를 이해해야 한다.
결정적인 정렬 만들기
SELECT order_id, created_at, amount
FROM orders
ORDER BY created_at DESC, order_id DESC;
created_at만 정렬하면 같은 시각의 행 순서는 결정되지 않는다. PK인 order_id를 Tie-breaker로 추가해야 반복 실행과 Pagination에서 안정적인 순서를 얻는다.
FETCH FIRST와 WITH TIES
-- 정확히 10행 이하
FETCH FIRST 10 ROWS ONLY
-- 10번째 행과 정렬값이 같은 동점까지 포함
FETCH FIRST 10 ROWS WITH TIES
WITH TIES는 반환 행 수가 10보다 많을 수 있다. 동점 기준은 전체 ORDER BY 표현식이므로 PK까지 포함하면 사실상 Tie가 없어질 수 있다.
ROWNUM의 올바른 위치
SELECT *
FROM (
SELECT order_id, amount
FROM orders
ORDER BY amount DESC, order_id
)
WHERE ROWNUM <= 10;
ROWNUM을 정렬과 같은 Query Block에 두면 먼저 선택된 행을 정렬할 수 있다. Oracle 12c 이상의 Row Limiting Clause를 사용하더라도 동점 행의 순서를 결정할 추가 정렬 기준이 필요하다.
NULL 정렬
Oracle의 기본 NULL 위치는 정렬 방향에 따라 달라질 수 있으므로 업무 요구가 있으면 NULLS FIRST 또는 NULLS LAST를 명시한다. SQL 결과 순서는 ORDER BY 없이는 보장되지 않는다.
시험 포인트
Oracle ROWNUM
ROWNUM은 같은 쿼리 블록의 ORDER BY보다 먼저 붙을 수 있다. 먼저 정렬한 뒤 바깥에서 제한한다.
SELECT *
FROM (
SELECT team_name, wins
FROM team_score
ORDER BY wins DESC
)
WHERE ROWNUM <= 3;
동점까지 포함하려면 RANK나 DENSE_RANK, 또는 DBMS가 지원하는 FETCH FIRST 3 ROWS WITH TIES를 사용한다.
SELECT *
FROM team_score
ORDER BY wins DESC
FETCH FIRST 3 ROWS WITH TIES;
SQL Server의 TOP (3) WITH TIES도 ORDER BY의 마지막 경계값과 같은 행을 함께 반환한다.
순위 함수 선택
- 정확히 N행이 필요하면 결정적 ORDER BY와
ROW_NUMBER. - 동점 다음 순위를 건너뛰는 경기 순위면
RANK. - 동점 뒤에도 연속 순위면
DENSE_RANK.
정렬 기준이 유일하지 않으면 같은 점수의 행 순서는 달라질 수 있으므로 정확히 N행을 요구할 때는 PK 같은 보조 정렬키를 추가한다.
자주 틀리는 부분
- ORDER BY의 숫자는 SELECT 목록의 위치를 뜻할 수 있지만 유지보수성이 낮다.
- Top-N에서 동점 처리 여부와 정확히 N행 반환 여부를 구분한다.
- 페이지 번호가 깊어질수록 OFFSET 방식은 앞 행을 계속 처리해야 할 수 있다.
복습 문제
답을 생각한 뒤 정답과 근거를 펼쳐 보세요.
동점이 있는 결과에 PK 정렬을 추가하는 이유는?
정답과 근거
동률 행의 상대 순서를 하나로 고정해 페이지 경계와 Top-N 결과를 반복 실행해도 같게 만들기 위해서입니다.
ROWNUM과 ORDER BY를 같은 단계에서 단순 결합하면 생길 수 있는 문제는?
정답과 근거
ROWNUM이 정렬 전에 부여되면 임의의 N행을 고른 뒤 그 행만 정렬하는 결과가 될 수 있습니다.
동점 급여가 있는 상위 3행을 안정적으로 재현하려면 정렬 목록에 어떤 고유 키를 추가해야 하는가?
정답과 근거
ORDER BY salary DESC, employee_id처럼 업무 정렬 뒤에 PK 또는 다른 고유 키를 추가합니다.