0Pricing
SQL Interview Prep · 강의

DENSE_RANK로 n번째로 높은 값 찾기

n번째 고유 값으로 일반화하고 중복을 처리합니다.

DENSE_RANK로 n번째로 높은 값 찾기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

N번째로 높은 값으로 일반화하기

두 번째로 높은 급여를 찾을 수 있게 되면 면접관은 곧바로 다음과 같이 질문합니다. "그럼 이제 N번째로 높은 급여를 구해 보세요." 가장 깔끔하고 근거가 분명한 답변은 DENSE_RANK를 사용하는 것입니다.

패턴은 항상 같습니다. 서로 다른 급여에 내림차순으로 순위를 매긴 다음, 순위가 N인 행을 필터링합니다. N이 바뀌어도 논리는 변하지 않으므로, 이 하나의 방법으로 이 유형의 질문 전체에 답할 수 있습니다.

이제 이 방법을 단계적으로 만들고, 동률과 중복을 처리하며, "서로 다른 값"이라는 의미에 DENSE_RANK가 적합한 순위 함수인 이유를 살펴보겠습니다.

핵심 템플릿

다음은 재사용할 수 있는 N번째로 높은 값의 템플릿입니다. 면접관이 요구하는 N에 맞게 상수를 바꾸십시오.

내부 쿼리에서 DENSE_RANK를 계산합니다(윈도 함수는 WHERE 안에 사용할 수 없습니다). 그런 다음 바깥에서 rnk = N을 필터링합니다. 세 번째로 높은 급여를 찾으려면 필터를 rnk = 3으로 설정하십시오.

SELECT salary AS nth_highest
FROM (
  SELECT salary,
         DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
  FROM employee
) ranked
WHERE rnk = 3;

DENSE_RANK가 서로 다른 값에 순위를 매기는 방식

DENSE_RANK는 같은 값에 같은 순위를 부여하고 그 뒤에 빈 순위를 만들지 않습니다. 이것이 바로 면접관이 말하는 "N번째로 서로 다른 값"의 정의입니다.

급여가 800, 800, 600, 600, 400인 경우:

  • 800 -> 순위 1
  • 600 -> 순위 2
  • 400 -> 순위 3

따라서 행은 다섯 개지만 세 번째로 높은 급여는 400입니다. 중복은 자동으로 하나의 순위로 합쳐집니다.

RANK가 잘못된 결과를 내는 이유

RANK로 바꾸면 결과가 잘못됩니다. RANK는 동률의 개수에 비례해 빈 순위를 만듭니다.

급여가 800, 800, 600, 600, 400인 경우:

  • 800, 800 -> 순위 1(두 행)
  • 600, 600 -> 순위 3(순위 2가 없는 빈 구간)
  • 400 -> 순위 5

rnk = 3으로 필터링하면 600을 반환하고, rnk = 2로 필터링하면 아무것도 반환하지 않습니다. 면접관이 특별히 경쟁 순위 방식을 원하는 경우가 아니라면, "N번째로 서로 다른 급여"에는 DENSE_RANK가 올바릅니다.

ROW_NUMBER도 여기서는 잘못된 이유

ROW_NUMBER는 동률을 완전히 무시하고 모든 행에 고유한 번호를 부여합니다. 급여가 800, 800, 600, 600, 400이면 1, 2, 3, 4, 5를 생성합니다.

따라서 rn = 3은 600을 반환하지만, rn = 2는 서로 다른 두 번째 값이 아니라 중복된 800을 반환합니다. ROW_NUMBER는 "N번째 서로 다른 값"이 아니라 "N번째 행"에 답합니다.

중복 제거처럼 실제로 특정 행을 원하거나, 그룹별 상위 N개 중 정확히 한 행만 남기려는 경우에만 ROW_NUMBER를 사용하십시오.

SELECT salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
FROM employee;

N을 안전하게 매개변수화하기

실제 코드에서는 순위를 하드코딩하지 않습니다. N을 매개변수로 전달하고 그 값과 비교합니다. 윈도 정의는 그대로 유지하고, 바깥 필터만 매개변수화합니다.

이 방법을 사용하면 순위 N에서 동률인 급여를 모두 반환할 수도 있습니다. DENSE_RANK는 동률인 값에 같은 순위를 부여하므로, 여러 직원이 N번째로 서로 다른 급여를 공유하면 WHERE rnk = N이 여러 행을 반환할 수 있으며, 이는 원하는 결과인 경우가 많습니다.

SELECT id, salary
FROM (
  SELECT id, salary,
         DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
  FROM employee
) ranked
WHERE rnk = :n;

상관 개수 세기의 일반화

윈도 함수를 사용하지 않는 방법도 일반화할 수 있습니다. 어떤 급여보다 엄격하게 높은 서로 다른 급여가 정확히 N - 1개라면, 그 급여는 N번째로 높은 서로 다른 급여입니다.

세 번째로 높은 급여를 찾으려면 그보다 높은 서로 다른 급여가 정확히 2개여야 합니다. 이 방법은 윈도 함수가 없는 오래된 데이터베이스 엔진에서도 작동하지만, 내부 개수가 바깥 쿼리의 각 행마다 다시 실행되므로 확장성이 떨어집니다.

SELECT DISTINCT salary AS nth_highest
FROM employee e
WHERE (
  SELECT COUNT(DISTINCT e2.salary)
  FROM employee e2
  WHERE e2.salary > e.salary
) = 2;

면접관이 요구하는 MySQL 함수 형태

LeetCode 형식의 "N번째로 높은 급여" 문제에서는 단일 값을 반환하는 저장 함수를 요구하는 경우가 많습니다. 본문은 하나의 급여를 반환하도록 감싼 DENSE_RANK 템플릿일 뿐입니다.

면접에서 정확한 함수 구문을 외울 필요는 없지만, 서로 다른 급여를 대상으로 LIMIT N-1, 1을 사용하는 것이 간결한 MySQL 관용 표현이라는 점은 알아 둘 만합니다.

SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
LIMIT 1 OFFSET 2;  -- N = 3, so OFFSET N-1

예제: 네 번째로 높은 값

급여: 1000, 900, 900, 700, 500, 500, 300.

서로 다른 값을 내림차순으로 정렬하고 DENSE_RANK를 적용하면:

  • 1000 -> 1
  • 900 -> 2
  • 700 -> 3
  • 500 -> 4
  • 300 -> 5

네 번째로 높은 급여는 500입니다. 두 500 행은 모두 순위 4를 공유하므로, 식별자도 함께 조회하면서 rnk = 4로 필터링하면 500을 받는 두 직원이 모두 반환됩니다.

성능 참고 사항

규모가 커졌을 때 각 방법은 어떻게 비교될까요?

  • DENSE_RANK: 데이터 전체를 한 번 정렬한 다음 필터링합니다. 효율적이며, 실행 계획기가 급여 정렬에 급여 인덱스를 사용할 수 있습니다.
  • 상관 개수 세기: 내부 집계가 행마다 실행되므로 O(n의 제곱)이 될 가능성이 있습니다. 큰 테이블에서는 피하십시오.
  • LIMIT/OFFSET: 작은 N에서는 빠르지만 여전히 정렬이 필요하며, 큰 OFFSET은 많은 행을 읽고 버리게 합니다.

DENSE_RANK를 우선 제시하면 거의 잘못될 일이 없습니다.

언급할 경계 사례

역량 있는 지원자는 질문을 받기 전에 다음 경계 사례를 먼저 언급합니다:

  • N이 서로 다른 급여의 개수보다 큰 경우: 필터에 맞는 행이 없어 빈 결과를 반환합니다. 4단원에서는 하나의 NULL을 강제로 반환하는 방법을 다룹니다.
  • 순위 N에서 동률인 경우: DENSE_RANK는 동률인 직원을 모두 반환하므로, 이것이 원하는 결과인지 결정해야 합니다.
  • N = 1인 경우: 템플릿은 그대로 작동하며 최댓값을 반환합니다.

빠른 확인

N번째로 높은 값의 템플릿을 적용해 보시기 바랍니다.

요약

N번째로 높은 급여를 찾는 대표적인 방법은 하나입니다. 서브쿼리에서 DENSE_RANK() OVER (ORDER BY salary DESC)로 서로 다른 급여에 순위를 매긴 다음, WHERE rnk = N으로 필터링합니다.

  • DENSE_RANK는 동률이 같은 순위를 공유하고 빈 순위가 없는 "N번째로 서로 다른 값"을 의미합니다.
  • RANK는 빈 순위를 만들고, ROW_NUMBER는 값이 아니라 행을 셉니다.
  • 상관 개수 세기 = N-1 방법은 같은 아이디어를 윈도 함수 없이 일반화하지만 확장성이 떨어집니다.

"N이 존재하는 값의 개수를 초과하는 경우"라는 경계 사례를 항상 언급하시기 바랍니다. 다음에서 이 문제를 해결합니다.

자주 묻는 질문

“DENSE_RANK로 n번째로 높은 값 찾기” 강의는 무료인가요?

네 — “DENSE_RANK로 n번째로 높은 값 찾기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

“DENSE_RANK로 n번째로 높은 값 찾기”에서 뭘 배우나요?

n번째 고유 값으로 일반화하고 중복을 처리합니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

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

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

“DENSE_RANK로 n번째로 높은 값 찾기” 강의는 얼마나 걸리나요?

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

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

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

이 강의의 모든 강의

  1. 두 번째로 높은 급여를 찾는 다섯 가지 방법
  2. DENSE_RANK로 n번째로 높은 값 찾기
  3. 부서별 최고 연봉자
  4. n번째 값이 없을 때 NULL 반환하기
← SQL Interview Prep(으)로 돌아가기