본문 바로가기

Algorithm/MySQL

[LeetCode] 177. Nth Highest Salary (MySQL)

문제

  • Employee 테이블에서 n번째로 높은 salary 값을 출력하라
  • 예를 들어 n이 2이면 2번째로 높은 값인 200을 출력
  • 만약 n번째로 높은 salary가 없으면 null을 출력

코드

CASE문으로 풀기
  • 조건이 여러 개이고, 순차적으로 실행해야 하는 환경에 사용

1. SELECT 절로 먼저 뽑아보기

SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT N -- N = 2일 경우 2개의 레코드 값만 갖게 됨

2. 서브쿼리

SELECT MIN sub.Salary
FROM (
    SELECT DISTINCT Salary
    FROM Employee
    ORDER BY Salary DESC
    LIMIT N    
) sub

3. Case

-- n번째의 salary가 없다면 null을 출력
-- ex. 레코드는 3개인데 4번째로 큰 값을 출력해야하면 null 출력
SELECT  CASE WHEN COUNT(sub.Salary) < N THEN null 
             ELSE MIN(sub.Salary)
        END
FROM (
    SELECT DISTINCT Salary
    FROM Employee
    ORDER BY Salary DESC
    LIMIT N    
) sub

4. 함수 return 에 집어 넣기

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  RETURN (
      SELECT  CASE WHEN COUNT(sub.Salary) < N THEN null
                    ELSE MIN(sub.Salary)
                END
        FROM (
            SELECT DISTINCT Salary
            FROM Employee
            ORDER BY Salary DESC
            LIMIT N    
        ) sub
  );
END
IF문으로 풀기
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  RETURN (
        SELECT  IF(COUNT(sub.Salary) < N, null, MIN(Salary))
        FROM (
            SELECT DISTINCT Salary
            FROM Employee
            ORDER BY Salary DESC
            LIMIT N    
        ) sub
  );
END
  • IF 함수는 조건이 하나 밖에 없고 간단하게 사용하고 싶을 때 사용
  • IF function 형태 : IF(condition, value_if_true, value_if_false)
  • 1번에서 사용했던 서브쿼리 사용
  • 마찬가지로 salary를 카운트한 수보다 N이 크면 null, 아닐 경우 Salary의 최소값 출력
LIMIT 심화
SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT N-1, 1 <- N부터 1번째, 즉 N을 말함
  • 보통 LIMIT는 LIMIT 2 라고 썼을 때 2개의 ROW를 반환
  • 우리는 N번째 Salary값만 뽑아내면 되기 때문에 1개의 ROW만 필요함
  • 그래서 LIMIT ?, ? 형태를 사용하려고 함
  • LIMIT 2, 1 형태로 사용하면 2부터 2+1인 수를 반환할 수 있음. 즉 3번째 ROW만 뽑을 수 있음. 
  • 그러나 우리가 필요한 것은 2번째 ROW이기 때문에 첫 시작을 2-1로 줌. 
  • 즉, N값만 뽑아낼 수 있는 LIMIT N-1, 1 의 형태로 만듦
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  SET N = N-1;
  RETURN (
        SELECT DISTINCT Salary
        FROM Employee
        ORDER BY Salary DESC
        LIMIT N, 1
  );
END
  • 가져온 파라미터 N을 바로 수정하여 사용하기는 어려움
  • 변수를 선언하는 set 사용
  • N에서 1을 뺀 값을 다시 N에 넣어주고 LIMIT N, 1로 써준다
윈도우 함수
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  RETURN (
    SELECT MAX(sub.salary)
    FROM (
        SELECT DENSE_RANK() over (order by Salary DESC) as rk, Salary
        FROM Employee
        ) sub
    WHERE sub.rk = N
  );
END

출처

반응형