[LeetCode]177. Nth Highest Salary

주연·2023년 2월 20일
0

SQL 문제 풀이

목록 보기
17/28
post-thumbnail
post-custom-banner

230220

문제

https://leetcode.com/problems/nth-highest-salary/

입력받은 N번째에 해당하는 salary 출력, N번째가 없다면 null 출력

풀이

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    DECLARE highest INT

    SELECT salary
    FROM employee
    
    IF N NOT IN id THEN
        salary = null
    ELSE
        salary = N * 100
    RETURN (
        salary
      
  );
END

?ㅋ..사용자 정의 함수 처음 써보는데
1. N만 파라미터로 주면 테이블이랑 어떻게 비교하지? 라는 생각이 들었고
2. N과 id를 비교해서 값을 주고 싶은데 id에 해당하는 salary를 어떻게 뽑아야할지 모르겠다.
3. return에 select를 써도 되는건지, begin 문자체에 select를 써도 되는건지 모르겠다.

결국 풀이 보기로 결정 ^^..

CASE문 이용

  • 문제 풀이 확인
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

아 그냥 쿼리문 작성해서 return에 넣었구나

이 쿼리에서 중요 포인트라고 생각되는 것
1. nth highest값을 구해야하기 때문에 ORDER BY 내림차순해서 LIMIT
2. DISTINCT
id salary
1 300
2 300
3 200
4 100
이렇게 되어 있을 경우 getNthHighestSalary(2)를 구하면 200이 나와야하지만 300 값이 중복으로 존재해 300이 출력된다.
따라서 이 문제에서는 DISTINCT가 필요
3. COUNT(sub.salary) < N
LIMIT(N)개를 뽑았기 때문에 N만큼의 행이 없으면 당연히 COUNT(sub.salary)의 개수가 N보다 작을 것이다. 그래서 이를 이용해 N번째가 없다면~이 가능하다.
4. MIN(sub.salary)
내림차순으로 정렬했기 때문에 맨 밑에 있는 값이 문제에서 구하고자 하는 값이다. 따라서 MIN()을 이용해 최소값을 추출한다.

IF문 이용

  • 내가 풀어봄
CREATE FUNCTION getNthHighestSalary(N INT) 
RETURNS INT
BEGIN
    RETURN (
        SELECT IF(COUNT(sub.salary) < N, NULL, MIN(sub.salary))
        FROM (
            SELECT DISTINCT salary
            FROM Employee
            ORDER BY salary DESC
            LIMIT N
        ) sub    
  );
END

위 코드에서 case문을 if문으로만 수정했다.

LIMIT, OFFSET 활용

CREATE FUNCTION getNthHighestSalary(N INT) 
RETURNS INT
BEGIN
    RETURN (
        SELECT DISTINCT salary
        FROM Employee
        ORDER BY salary DESC
        LIMIT N-1,1 #N번째 값 가져와라
  );
END

이렇게 했더니 에러남.

CREATE FUNCTION getNthHighestSalary(N INT) 
RETURNS INT
BEGIN
    DECLARE highest = N-1 INT;
    RETURN (
        SELECT DISTINCT salary
        FROM Employee
        ORDER BY salary DESC
        LIMIT highest,1
  );
END

이렇게 선언해서 하려고 하는데 SET을 어떻게 이용해야할지 모르겠음.

  • 문제 풀이 확인

...DECLARE에서는 진짜 딱 변수 선언만 하는 것이라서 다음과 같이 수정하면 된다.

CREATE FUNCTION getNthHighestSalary(N INT) 
RETURNS INT
BEGIN
    DECLARE highest INT;
    SET highest = N-1;
    RETURN (
        SELECT DISTINCT salary
        FROM Employee
        ORDER BY salary DESC
        LIMIT highest,1
  );
END

선언하지 않고도 가능하다고 하다. (재정의)

CREATE FUNCTION getNthHighestSalary(N INT) 
RETURNS INT
BEGIN
    SET N = N-1; #N을 재정의
    RETURN (
        SELECT DISTINCT salary
        FROM Employee
        ORDER BY salary DESC
        LIMIT N,1 
        # LIMIT 1 OFFSET N (같음)
  );
END

-> 장점: 서브쿼리를 쓰지 않아도 된다.
집계함수 사용하지 않아도 된다.
값 없으면 자동으로 NULL 출력

profile
공부 기록
post-custom-banner

0개의 댓글