0Pricing
SQL Interview Prep · 강의

두 번째로 높은 급여를 찾는 다섯 가지 방법

하위 쿼리, LIMIT/OFFSET, 윈도 함수 해결책을 비교합니다.

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

누구나 받는 질문

“두 번째로 높은 급여를 찾으십시오”는 SQL 면접에서 가장 많이 나오는 단일 질문입니다. 정답이 여러 가지이고 미묘한 함정도 많기 때문에 면접관이 즐겨 출제합니다.

id와 salary 열이 있는 employee 테이블을 가정하십시오. 목표는 두 번째로 높은 서로 다른 급여 값을 반환하는 것입니다.

  • 급여가 300, 200, 200, 100이라면 정답은 두 번째 행이 아니라 200입니다.
  • 두 번째로 서로 다른 급여가 없다면 일반적으로 기대되는 정답은 NULL입니다.

다음 장면들에서는 이 문제를 다섯 가지 방법으로 해결하고 각 방법이 빛을 발하는 경우를 살펴봅니다.

CREATE TABLE employee (
  id     INT PRIMARY KEY,
  salary INT
);

방법 1: MAX보다 작은 값 중 MAX

가장 직관적인 해법은 두 번째로 높은 급여가 전체 최댓값보다 엄격하게 작은 급여 중 가장 큰 값이라는 점을 이용하는 것입니다.

영어 문장처럼 거의 그대로 읽히며 모든 SQL 문법 체계에서 작동합니다. 내부 하위 질의가 최댓값을 찾고, 외부 MAX가 그보다 작은 값 중 가장 큰 값을 찾습니다.

추가 장점: 두 번째로 서로 다른 급여가 없다면 외부 MAX가 0개 행을 집계하여 자동으로 NULL을 반환합니다. 면접관이 원하는 결과인 NULL을 별도의 처리 없이 얻을 수 있습니다.

SELECT MAX(salary) AS second_highest
FROM employee
WHERE salary < (SELECT MAX(salary) FROM employee);

서브쿼리가 중복을 처리하는 이유

방법 1에서는 DISTINCT를 전혀 사용하지 않았는데도 중복이 올바르게 처리된다는 점에 주목하시기 바랍니다.

세 사람이 200을 받고 최고 급여가 300이라면, 내부 쿼리는 300을 반환합니다. 바깥 필터는 300 미만인 모든 행을 남기고, 그중 MAX는 200이 몇 개 있든 관계없이 200입니다.

이것이 핵심 통찰입니다. 집계 함수가 중복을 대신 하나로 합쳐 줍니다. 집계 함수가 이미 올바르게 처리하는데도 많은 지원자가 DISTINCT를 사용해 불필요하게 복잡하게 만듭니다.

방법 2: LIMIT과 OFFSET

MySQL과 PostgreSQL에서는 서로 다른 급여를 내림차순으로 정렬한 뒤 첫 번째 값을 건너뛸 수 있습니다.

  • OFFSET 1은 가장 높은 값을 건너뜁니다.
  • LIMIT 1은 그다음 값 하나만 남깁니다.

여기서는 DISTINCT가 필수입니다. 그렇지 않으면 가장 높은 급여가 중복될 때 OFFSET 1이 실제 2위 급여가 아니라 최댓값의 중복 항목을 가리키게 됩니다.

함정: 두 번째로 서로 다른 값이 없으면 NULL이 아니라 행을 반환하지 않습니다. 이 경계 사례는 4단원에서 해결하겠습니다.

SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
LIMIT 1 OFFSET 1;

방법 3: SQL Server와 Oracle을 위한 FETCH

SQL Server와 최신 Oracle은 LIMIT ... OFFSET을 지원하지 않습니다. 대신 ANSI 표준인 OFFSET ... FETCH 구문을 사용합니다.

논리는 방법 2와 같습니다. 서로 다른 급여를 내림차순으로 정렬하고, 한 행을 건너뛴 다음 한 행을 가져옵니다. 데이터베이스별 문법을 알고 있다는 점은 면접관에게 실무 경험이 있음을 보여 줍니다.

SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
OFFSET 1 ROWS
FETCH NEXT 1 ROWS ONLY;

방법 4: DENSE_RANK 윈도 함수

현대적이고 확장 가능한 방법은 윈도 함수를 사용하는 것입니다. DENSE_RANK는 가장 높은 급여에 순위 1을, 그다음으로 서로 다른 급여에 순위 2를 할당하며, 동률인 급여에는 빈 순위 없이 같은 순위를 부여합니다.

서브쿼리에서 순위를 계산한 다음 바깥 쿼리에서 순위 2만 필터링합니다. 윈도 함수는 WHERE에서 직접 필터링할 수 없으므로 서브쿼리로 감싸는 작업이 반드시 필요하다는 점을 기억하시기 바랍니다.

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

DENSE_RANK를 RANK나 ROW_NUMBER가 아닌 이유

순위 함수의 선택은 "서로 다른" 의미를 처리할 때 중요합니다:

  • ROW_NUMBER는 모든 행에 고유한 번호를 부여합니다. 따라서 두 사람이 300을 받으면 행 번호가 1과 2가 되고, 2위가 최고 급여의 중복 항목이 됩니다. 잘못된 결과입니다.
  • RANK는 동률 뒤에 빈 순위를 남깁니다. 300을 받는 두 사람은 순위 1을 받고, 그다음 급여는 순위 3으로 건너뜁니다. 순위 2로는 해당 급여를 찾을 수 없습니다. 잘못된 결과입니다.
  • DENSE_RANK는 동률에 같은 순위를 부여하고 빈 순위를 만들지 않으므로, 순위 2는 항상 두 번째로 서로 다른 급여를 의미합니다. 올바른 결과입니다.

방법 5: 상관 서브쿼리로 개수 세기

윈도 함수가 사용되기 전부터 쓰이던 고전적인 방법입니다. 어떤 급여보다 엄격하게 높은 서로 다른 급여가 정확히 N-1개라면, 그 급여는 N번째로 높은 급여입니다.

두 번째로 높은 급여를 찾으려면 그보다 높은 서로 다른 급여가 정확히 하나 있어야 합니다. 우아한 방법이지만, 내부 개수가 바깥 쿼리의 각 행마다 실행되므로 큰 테이블에서는 느릴 수 있습니다.

개수를 N - 1로 바꾸면 N번째로 높은 급여로 자연스럽게 일반화할 수 있기 때문에, 면접관들이 이 방법을 보고 싶어 합니다.

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

완성된 예제를 처음부터 끝까지

급여가 500, 500, 350, 350, 100이라고 가정해 보겠습니다.

  • 방법 1: MAX는 500이고, 500보다 작은 값 중 가장 큰 값은 350입니다. 답은 350입니다.
  • 방법 4 (DENSE_RANK): 500 -> 순위 1, 350 -> 순위 2, 100 -> 순위 3입니다. 순위 2는 350입니다.
  • 방법 5: 급여가 350인 경우 그보다 높은 서로 다른 급여는 500 하나뿐입니다. 조건에 맞습니다. 답은 350입니다.

중복이 있어도 다섯 가지 방법의 결과는 모두 같습니다. 두 번째로 높은 서로 다른 급여는 350입니다.

어떤 방법을 선택해야 할까요

면접 조언:

  • 먼저 질문을 명확히 하십시오: "서로 다른 급여를 원하시나요? 그런 급여가 없으면 NULL을 원하시나요?" 명확히 확인하면 좋은 평가를 받을 수 있습니다.
  • DENSE_RANK가 가장 강력한 기본 답변입니다. N번째 값이나 그룹별 문제로도 깔끔하게 일반화할 수 있습니다.
  • MAX보다 작은 값 중 MAX는 가장 좋은 한 줄 표현이며, 추가 처리 없이 NULL을 반환합니다.
  • LIMIT/OFFSET은 간결하지만 DBMS별로 다르고, 경계 사례에서는 행을 반환하지 않습니다.

장단점을 소리 내어 설명하는 것이 중급 수준의 답변과 초급 수준의 답변을 가르는 요소입니다.

흔히 하는 실수 피하기

면접관이 숨겨 둔 다음 함정에 주의하시기 바랍니다:

  • DENSE_RANK 대신 ROW_NUMBER를 사용해 최고 급여가 두 번 나오는 경우
  • 최댓값이 중복될 때 LIMIT/OFFSET 버전에서 DISTINCT를 잊는 경우
  • ORDER BY salary DESC LIMIT 1,1이 서로 다른 값을 반환한다고 가정하는 경우(그렇지 않습니다)
  • 두 번째 값이 아니라 두 번째 행을 반환하는 경우

빠른 확인

순위 함수 선택에 대한 이해도를 확인해 보시기 바랍니다.

요약

이제 두 번째로 높은 급여를 찾는 다섯 가지 방법을 알게 되었습니다:

  • MAX보다 작은 값 중 MAX - 이식성이 높고, 추가 처리 없이 NULL을 반환합니다.
  • LIMIT/OFFSET 및 OFFSET/FETCH - 간결하지만 DBMS별로 다릅니다.
  • DENSE_RANK - 확장성이 높고 동률을 올바르게 처리하는 기본 방법입니다.
  • 상관 개수 세기 - 우아하며 N번째 값으로 일반화할 수 있습니다.

핵심 요점은 서로 다른 값이 필요한지 확인하고, 동률에는 DENSE_RANK를 우선 사용하며, 두 번째 값이 없을 때 어떤 방법이 NULL을 반환하고 어떤 방법이 행을 반환하지 않는지 기억하는 것입니다.

자주 묻는 질문

“두 번째로 높은 급여를 찾는 다섯 가지 방법” 강의는 무료인가요?

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

“두 번째로 높은 급여를 찾는 다섯 가지 방법”에서 뭘 배우나요?

하위 쿼리, LIMIT/OFFSET, 윈도 함수 해결책을 비교합니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

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

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

“두 번째로 높은 급여를 찾는 다섯 가지 방법” 강의는 얼마나 걸리나요?

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

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

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

이 강의의 모든 강의

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