상위 N개 행 안정적으로 반환하기
동점 처리 기준이 없으면 ORDER BY와 LIMIT의 결과가 비결정적일 수 있는 이유를 알아봅니다.
상위 N개 행 안정적으로 반환하기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
상위 N개 쿼리의 숨은 버그
"급여가 가장 높은 직원 5명을 보여 주세요"라는 요청은 쉬워 보입니다. ORDER BY salary DESC LIMIT 5처럼 작성하면 됩니다. 하지만 면접관은 함정을 심어 둡니다. 경계에서 여섯 명의 급여가 같다면 어떻게 될까요? 동률인 행이 많다면 어떻게 될까요?
핵심 문제는 결정성입니다. 정렬 키에 동률이 있으면 LIMIT가 임의로 잘라 내므로, 반환되는 정확한 행이 실행할 때마다 달라질 수 있습니다. 이 레슨에서는 상위 N개 결과를 신뢰할 수 있게 만드는 방법을 다룹니다.
ORDER BY + LIMIT가 비결정적일 수 있는 이유
4위, 5위, 6위의 급여가 모두 50000이라고 가정해 보십시오. ORDER BY salary DESC LIMIT 5는 정확히 5개 행을 반환해야 하므로, 동률인 세 행 중 두 개만 남기고 하나는 제외합니다. 그러나 어떤 두 행을 남길지는 정의되어 있지 않습니다.
쿼리를 두 번 실행하거나 최적화 프로그램이 실행 계획을 변경한 후 실행하면 서로 다른 사람이 반환될 수 있습니다. 면접관이 찾기를 원하는 버그가 바로 이 비결정성입니다.
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;해결책 1: 고유한 동률 해소 기준 추가
가장 간단한 해결책은 일반적으로 기본 키처럼 고유한 열을 추가하여 정렬 순서를 완전히 정하는 것입니다. 이제 전체 키가 같은 두 행이 없으므로, 어디에서 잘릴지가 결정적이고 재현 가능합니다.
이렇게 해도 어떤 급여가 나타나는지는 바뀌지 않지만, 동률인 행 중 어떤 행을 선택할지가 실행할 때마다 안정적으로 유지됩니다.
SELECT id, name, salary
FROM employees
ORDER BY salary DESC, id ASC
LIMIT 5;해결책 2: WITH TIES로 모든 동률 포함
때로는 정확히 N개 행이 아니라 "경계값과 동률인 모든 행을 포함하라"는 요구 사항이 있습니다. 표준 SQL과 SQL Server는 WITH TIES를 제공하며, 마지막 행의 ORDER BY 값과 일치하는 추가 행을 반환합니다.
5위 급여를 받는 사람이 세 명이라면 7개 행이 반환됩니다. WITH TIES에는 ORDER BY가 필요하다는 점에 유의하십시오.
SELECT name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 5 ROWS WITH TIES;먼저 요구 사항을 명확히 하십시오
코딩하기 전에 면접관에게 다음과 같이 질문하십시오. "경계에서 동률이 발생하면 정확히 N개 행을 원하시나요, 아니면 동률인 모든 행을 원하시나요?" 이 한 가지 확인 질문만으로도 경력과 경험을 보여 줄 수 있습니다.
- 정확히 N개이며 안정적인 결과: 고유한 동률 해소 기준을 추가합니다.
- 모든 동률 포함:
WITH TIES또는RANK를 사용합니다. - 서로 다른 값:
DENSE_RANK를 사용합니다.
이식성 높은 윈도 함수 방식
많은 엔진에는 WITH TIES가 없습니다. 이식성과 활용도가 높은 패턴은 하위 쿼리나 CTE에서 순위 윈도 함수를 사용한 다음 순위로 필터링하는 것입니다. ROW_NUMBER는 결정적인 정렬 키를 사용해 정확히 N개 행을 반환합니다.
윈도 함수는 WHERE에서 직접 참조할 수 없으므로 쿼리로 감싸야 합니다.
SELECT name, salary
FROM (
SELECT name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC, id ASC) AS rn
FROM employees
) ranked
WHERE rn <= 5;동률을 유지하는 RANK
동률인 모든 행을 유지하면서 순위에 빈 번호를 두고 싶다면 ROW_NUMBER를 RANK로 바꾸십시오. 세 행이 4위로 동률이면 모두 4위가 되고 다음 순위는 7위가 됩니다.
그런 다음 rank <= 5로 필터링하면 동률을 포함한 급여 상위 5개 순위의 모든 행이 반환됩니다.
SELECT name, salary
FROM (
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 5;서로 다른 상위 N개 값에는 DENSE_RANK
"급여 상위 3개 수준"은 상위 3명의 사람이 아니라 서로 다른 값을 의미합니다. DENSE_RANK는 동률에 같은 순위를 할당하고 번호를 건너뛰지 않으므로, dense_rnk <= 3은 서로 다른 급여 중 가장 높은 세 값 중 하나를 받는 모든 사람을 반환합니다.
어떤 표현에 어떤 순위 함수를 사용해야 하는지 아는 것은 면접에서 실력을 뚜렷하게 보여 주는 요소입니다.
SELECT name, salary
FROM (
SELECT name, salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees
) ranked
WHERE drnk <= 3;상위 1개 특수 사례
단일 최상위 행에는 ORDER BY ... LIMIT 1을 사용할 수 있지만 여전히 동률 문제가 발생할 수 있습니다. 최댓값을 가진 모든 행을 원한다면 하위 쿼리의 최댓값과 비교하거나 RANK() = 1을 사용하십시오.
최댓값 하위 쿼리 방식은 깔끔하고 어떤 SQL 방언에서도 실행됩니다.
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);방식 비교
신뢰할 수 있는 상위 N개 결과를 위해 각 방법을 사용하는 경우를 요약하면 다음과 같습니다.
LIMIT+ 고유한 동률 해소 기준: 정확히 N개 행, 안정적이며 가장 간단합니다.FETCH ... WITH TIES: 정확히 N개에 경계 동률을 더하며, 표준 SQL 방식입니다.ROW_NUMBER: 정확히 N개이며 결정적이고 완전히 이식 가능합니다.RANK: 모든 동률을 포함한 상위 N개 순위입니다.DENSE_RANK: 서로 다른 상위 N개 값입니다.
그룹별 상위 N개 미리 보기
윈도 방식은 훌륭하게 일반화됩니다. PARTITION BY를 추가하면 각 그룹 안에서 상위 N개를 가져올 수 있습니다. 예를 들어 부서별로 급여가 가장 높은 사람 2명을 가져오는 식입니다. 분할한 후에도 동일하게 rn <= n으로 필터링합니다.
그룹별 상위 N개 문제는 실제 면접에서 가장 자주 출제되는 문제 중 하나이며, 방금 배운 것과 정확히 같은 패턴을 기반으로 합니다.
SELECT department, name, salary
FROM (
SELECT department, name, salary,
ROW_NUMBER() OVER (PARTITION BY department
ORDER BY salary DESC, id ASC) AS rn
FROM employees
) ranked
WHERE rn <= 2;빠른 확인
요구 사항을 올바른 함수와 연결하십시오.
요약
상위 N개 결과를 신뢰할 수 있게 반환하려면 다음을 따르십시오.
- 정렬 키에 동률이 있을 때
ORDER BY ... LIMIT만 사용하면 비결정적입니다. - 안정적으로 정확히 N개 결과를 얻으려면 고유한 동률 해소 기준을 추가하십시오.
- 경계의 동률을 유지하려면
WITH TIES또는RANK를 사용하십시오. - 서로 다른 상위 N개 값에는
DENSE_RANK를 사용하십시오. - 면접관이 정확히 N개 행을 원하는지, 아니면 동률인 모든 행을 원하는지 항상 먼저 확인하십시오.
자주 묻는 질문
“상위 N개 행 안정적으로 반환하기” 강의는 무료인가요?
네 — “상위 N개 행 안정적으로 반환하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“상위 N개 행 안정적으로 반환하기”에서 뭘 배우나요?
동점 처리 기준이 없으면 ORDER BY와 LIMIT의 결과가 비결정적일 수 있는 이유를 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“상위 N개 행 안정적으로 반환하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 여러 열 정렬과 NULL 배치
- LIMIT, OFFSET과 FETCH FIRST
- 상위 N개 행 안정적으로 반환하기
- 수식과 별칭으로 정렬하기