[SQL] Leetcode 176 : Second Highest Salary

양승우·2025년 2월 19일

코드카타

목록 보기
49/58

문제

Leetcode 176 : Second Highest Salary

Employee 테이블에서 2번째로 높은 Salary를 찾는 문제
만약 2번째로 높은 값이 없다면 null을 반환해야 한다

풀이

count(*)를 통한 조건 설정

이 문제를 처음 접했을 때 가장 먼저 구상했던 풀이 방법이다.
row_number() over (order by salary desc)를 통해서 rn을 구하고,
rn=2인 값을 뽑으면 간단히 문제 해결!

이라고 생각했지만,
WHERE절에 rn=2를 넣으면, FROM에서 애초에 rn=2인 값이 존재하지 않는 데이터의 경우에는 null조차 반환하지 못 한다

이를 해결하기 위해 CASE END 조건문에 count(*)를 넣을 수 있다
FROM절에서 (WHERE 처리까지 하고) 반환된 값이 0개라면 -> rn=2인 값이 없는 상태
1개라면 -> rn=2인 값이 있는 상태
로 볼 수 있기 때문.

SELECT
    CASE
        when count(*)=0 then null
        else salary
    end as "SecondHighestSalary"
FROM (
    SELECT
        salary
        , row_number() over (order by salary desc) as "rn"
    FROM
        (SELECT
            distinct salary
        FROM
            Employee
        ) a
) aa
WHERE
    rn = 2
;

max()를 사용해 null 표기

위에서 고민했던 부분이 'null이 출력되지 않는 경우'였다.
이를 해결하기 위해 max() 함수를 사용할 수 있다.

MAX() 함수는 집계 함수이다. 집계 함수는 입력으로 받은 행들이 하나도 없을 때, 즉 빈 집합에 대해 적용되면 결과로 NULL을 반환하는 특징이 있다.
이를 통해 별도로 조건을 걸지 않아도 값이 없다면 null이 출력되게 할 수 있다.

SELECT 
    MAX(salary) AS "SecondHighestSalary"
FROM (
    SELECT 
        salary
        , ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
    FROM (
        SELECT 
            DISTINCT salary 
        FROM 
            Employee) a
) b
WHERE rn = 2
;

(mysql) LIMIT & OFFSET 사용

참고: [MYSQL] 📚 LIMIT / OFFSET 쿼리

LIMIT는 단순히 ‘몇 개’를 가져온다에 그치지 않고 ‘어디서부터’를 지정해줄 수도 있다

LIMIT 2 : 처음부터 2개 출력하기 (1~2)
LIMIT 1, 2 : 1번째 행 후부터 2개 출력하기 (2~3)
LIMIT 2 OFFSET 1 : 1번째 행 후부터 2개 출력하기 (2~3)

이를 통해 "2번째 행부터 1개"를 지정해주면 문제에서 요구하는 바를 정확하게 뽑아낼 수 있다

다만, 그냥 LIMIT만 사용하면 null 처리가 불가능하기 때문에,
값이 존재하지 않을 경우 null을 출력하기 위해 SELECT 문으로 전체 결과를 감싸주어야 한다

SELECT (
    SELECT
        distinct salary
    FROM 
        Employee
    ORDER BY
        salary desc
    LIMIT
        1, 1
) as "SecondHighestSalary"
;
profile
어제보다 오늘 더

0개의 댓글