0Pricing
SQL Interview Prep · 강의

동점 상황에서 RANK와 DENSE_RANK 비교하기

값이 같은 경우 순위에 간격이 생기는 방식과 생기지 않는 방식을 묻는 고전적인 질문을 다룹니다.

동점 상황에서 RANK와 DENSE_RANK 비교하기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL 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 90

SQL 방언 간 참고 사항

좋은 소식입니다. 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로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

“동점 상황에서 RANK와 DENSE_RANK 비교하기”에서 뭘 배우나요?

값이 같은 경우 순위에 간격이 생기는 방식과 생기지 않는 방식을 묻는 고전적인 질문을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“동점 상황에서 RANK와 DENSE_RANK 비교하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. OVER, PARTITION BY와 ORDER BY
  2. ROW_NUMBER로 고유한 순서 부여하기
  3. 동점 상황에서 RANK와 DENSE_RANK 비교하기
  4. 윈도 결과로 필터링하기
← SQL Interview Prep(으)로 돌아가기