동점 상황에서 RANK와 DENSE_RANK 비교하기
값이 같은 경우 순위에 간격이 생기는 방식과 생기지 않는 방식을 묻는 고전적인 질문을 다룹니다.
동점 상황에서 RANK와 DENSE_RANK 비교하기은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
세 가지 순위 함수 나란히 비교
SQL에는 세 가지 순위 윈도 함수가 있으며, 윈도에 관한 질문 중 가장 자주 나오는 것은 동률일 때 세 함수가 어떻게 다른지 묻는 것입니다.
- ROW_NUMBER — 항상 고유합니다. 동률인 행에는 서로 다른 번호가 임의로 부여됩니다.
- RANK — 동률인 행은 같은 순위를 받고, 다음 순위는 건너뜁니다(간격이 생깁니다).
- DENSE_RANK — 동률인 행은 같은 순위를 받지만, 다음 순위는 건너뛰지 않습니다(간격이 없습니다).
이 차이를 즉시 설명할 수 있는 능력은 면접에서 확실한 역량 신호가 됩니다.
구체적인 예시 표
다섯 개의 점수를 내림차순으로 정렬했다고 생각해 보세요. 100, 90, 90, 80, 70입니다. 각 함수가 어떻게 번호를 매기는지 살펴보세요.
- ROW_NUMBER: 1, 2, 3, 4, 5
- RANK: 1, 2, 2, 4, 5 (동률 다음에 3을 건너뜁니다)
- DENSE_RANK: 1, 2, 2, 3, 4 (건너뛰지 않습니다)
이 100/90/90/80/70 예시를 외워 두면 질문에 바로 답할 수 있습니다.
SELECT
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS rownum,
RANK() OVER (ORDER BY score DESC) AS rnk,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;RANK가 간격을 계산하는 방식
RANK는 정렬 순서에서 해당 행보다 엄격하게 앞서는 행의 수에 1을 더한 값을 각 행의 순위로 지정합니다. 값이 90인 두 행은 100 하나에만 앞서므로 둘 다 순위 2를 받습니다. 그다음 더 낮은 값은 세 행에 앞서므로 순위가 4로 올라갑니다.
그래서 RANK는 경기 순위 산정 방식과 비슷합니다. 공동 은메달 수상자는 있지만 동메달은 없습니다.
-- scores 100,90,90,80 -> RANK = 1,2,2,4
SELECT score, RANK() OVER (ORDER BY score DESC) AS rnk
FROM scores;DENSE_RANK가 간격을 피하는 방식
DENSE_RANK는 현재 값보다 앞서는 서로 다른 값의 수에 1을 더한 값을 순위로 지정합니다. 90에서 동률이 발생한 뒤 80보다 앞선 서로 다른 값은 100과 90 두 개뿐이므로 80은 간격 없이 순위 3을 받습니다.
동률을 한 번만 세어야 하는 "두 번째로 높은 급여"처럼 서로 다른 값의 위치가 중요할 때 DENSE_RANK를 사용하세요.
-- scores 100,90,90,80 -> DENSE_RANK = 1,2,2,3
SELECT score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;각 함수를 선택할 때
면접관이 듣고 싶어 하는 빠른 판단 가이드입니다:
- 각 위치에 정확히 한 행이 필요하신가요 (최신 레코드, 페이지 매김)? → ROW_NUMBER입니다.
- 동률은 같은 순위이고 순위 건너뜀도 올바른 순위표가 필요하신가요 (스포츠 순위, 동률을 포함한 상위 3개)? → RANK입니다.
- N번째로 서로 다른 값이 필요하신가요 (N번째로 높은 급여)? → DENSE_RANK입니다.
잘못된 선택은 반환하는 행을 바꾸므로, 선택한 이유를 소리 내어 설명하세요.
파티션 내부 순위 매기기
세 함수 모두 PARTITION BY를 사용하여 각 그룹 내부에서 독립적으로 순위를 매길 수 있습니다. 각 파티션은 순위 1부터 다시 시작합니다.
이 예제에서는 각 부서가 급여를 기준으로 소속 직원을 따로 순위 매기며, 동률은 DENSE_RANK로 처리합니다. 각 부서의 최고 급여 직원은 순위 1이고, 같은 급여를 받는 직원들은 같은 순위를 공유합니다.
SELECT
department,
name,
salary,
DENSE_RANK() OVER (
PARTITION BY department
ORDER BY salary DESC
) AS salary_rank
FROM employees;실습 예제: 동률 포함 상위 3개
"부서별로 급여가 가장 높은 상위 3개를 반환하되, 3위에서 여러 사람이 동률이면 모두 포함하세요." 이 요구 사항에는 ROW_NUMBER가 아니라 RANK 또는 DENSE_RANK가 필요합니다.
DENSE_RANK <= 3을 사용하면 상위 세 개의 서로 다른 급여 수준과 해당 수준에 속한 모든 직원을 유지할 수 있습니다. 이것이 바로 "동률 포함"의 의미입니다.
SELECT department, name, salary, salary_rank
FROM (
SELECT department, name, salary,
DENSE_RANK() OVER (
PARTITION BY department ORDER BY salary DESC
) AS salary_rank
FROM employees
) t
WHERE salary_rank <= 3;실습 예제: 두 번째로 높은 급여
가장 유명한 SQL 면접 질문 중 하나입니다. 견고한 답은 DENSE_RANK를 사용하여, 가장 높은 급여가 중복되어도 실제 두 번째 값을 찾지 못하는 일이 없도록 합니다.
세 사람이 최고 급여를 받는 경우에도 DENSE_RANK = 2는 다음으로 서로 다른 급여를 올바르게 식별합니다. 반면 ROW_NUMBER = 2는 또 다른 최고 급여 수령자만 반환합니다.
SELECT DISTINCT salary AS second_highest
FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS dr
FROM employees
) t
WHERE dr = 2;N번째로 높은 값에서 RANK와 DENSE_RANK 비교
N번째로 높은 값을 찾는 문제에서 RANK보다 DENSE_RANK를 사용하는 이유는 무엇일까요? RANK는 순위 사이에 건너뜀을 만들기 때문입니다. 급여가 100, 100, 90이면 90의 RANK = 3이지만 DENSE_RANK = 2입니다.
질문이 "두 번째로 높은 서로 다른 급여"를 요구할 때 RANK = 2를 조건으로 걸러내면 아무 결과도 반환되지 않지만, DENSE_RANK = 2는 90을 올바르게 반환합니다. 항상 "N번째로 서로 다른 값"은 DENSE_RANK로 연결해서 생각하세요.
-- salaries 100,100,90
-- RANK: 1,1,3 -> WHERE rank = 2 returns NOTHING
-- DENSE_RANK: 1,1,2 -> WHERE dense_rank = 2 returns 90SQL 방언 간 참고 사항
좋은 소식입니다. ROW_NUMBER, RANK, DENSE_RANK는 SQL 표준에 포함되어 있으며 PostgreSQL, SQL 서버, 오라클, MySQL 8+, BigQuery, 스노플레이크에서 동일하게 동작합니다. 앞에서 설명한 동률 처리 방식은 어디서나 동일합니다.
관련 함수인 PERCENT_RANK는 RANK를 기반으로 0에서 1 사이의 상대적 위치를 제공합니다. 면접관이 백분위 순위에 관해 묻는다면 언급할 만합니다.
자주 하는 실수
다음 사항을 주의하세요:
- "N번째로 높은 값"에
ROW_NUMBER를 사용하여 동률인 행을 놓치는 것 - 서로 다른 값을 묻는 질문에
RANK를 사용한 뒤, 순위 건너뜀 때문에 결과가 비어 버리는 것 OVER내부에서ORDER BY를 빠뜨리는 것 — 순위 매기기는 이것 없이는 의미가 없습니다.- 외부 쿼리에서 걸러내지 않고
WHERE에서 직접 순위 결과를 걸러내는 것
빠른 확인
동률 처리 규칙을 적용해 보세요.
복습: 순위 건너뜀과 건너뜀 없음
이제 올바른 순위 함수를 즉시 선택할 수 있습니다:
- ROW_NUMBER: 고유한 번호를 부여하며, 같은 순위가 없습니다.
- RANK: 동률은 같은 순위를 공유하고, 그다음 순위에는 건너뜀이 생깁니다 (1,2,2,4).
- DENSE_RANK: 동률은 같은 순위를 공유하고, 순위 건너뜀이 없습니다 (1,2,2,3).
- "N번째로 높은 서로 다른 값" →
DENSE_RANK; "동률 포함 상위 N개" →RANK/DENSE_RANK; "위치마다 한 행" →ROW_NUMBER
다음은 윈도 결과를 실제로 걸러내는 방법입니다. WHERE에서는 이 작업을 할 수 없기 때문입니다.
자주 묻는 질문
“동점 상황에서 RANK와 DENSE_RANK 비교하기” 강의는 무료인가요?
네 — “동점 상황에서 RANK와 DENSE_RANK 비교하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“동점 상황에서 RANK와 DENSE_RANK 비교하기”에서 뭘 배우나요?
값이 같은 경우 순위에 간격이 생기는 방식과 생기지 않는 방식을 묻는 고전적인 질문을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“동점 상황에서 RANK와 DENSE_RANK 비교하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- OVER, PARTITION BY와 ORDER BY
- ROW_NUMBER로 고유한 순서 부여하기
- 동점 상황에서 RANK와 DENSE_RANK 비교하기
- 윈도 결과로 필터링하기