✅ 본 게시글은 학습 목적으로 LeetCode 문제의 풀이과정을 정리한 것이며, 모든 자료의 출처는 LeetCode에 있습니다.
Second Highest Salary - LeetCode
Can you solve this real interview question? Second Highest Salary - Table: Employee +-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | salary | int | +-------------+------+ id is the primary key (column with unique values)
leetcode.com
정답률 38.7%여서 조금 겁먹었지만..! 제출 성공하긴했다 ㅎㅎ
근데 Solutions를 보니 내 코드보다 훨~~씬 간결하고 예쁘게 쓴 것이 있어서 기록해둔다.
Employee 테이블에서 두 번째로 salary가 높은 사람을 출력하는 문제다.
만약, Example 2처럼 두 번째로 salary가 높은 사람이 존재하지 않는다면, null을 출력한다.
일단 내가 작성한 쿼리는 다음과 같다.
SELECT (CASE WHEN COUNT(DISTINCT salary) = 1 THEN NULL
ELSE (SELECT salary
FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY salary DESC) rn
FROM Employee
GROUP BY salary) sub
WHERE rn = 2)
END) AS SecondHighestSalary
FROM Employee;
보면 알 수 있다시피, 쿼리가 매우 복잡하고... 길고... 이상하고... 그렇다...
어찌저찌 제출은 성공했지만 별로 좋은 방법은 아닌 것 같다ㅠㅠ
먼저 내가 생각했던 원리를 말해보자면, '두 번째로 salary가 높은 사람'이 존재하지 않는 상황은 다음 두 가지다.
1) 행이 하나밖에 없는 경우
2) 행이 여러 개이지만 salary가 전부 똑같은 경우
이 두 가지 경우는 모두 COUNT(DISTINCT salary) = 1인 경우다.
따라서, CASE WHEN COUNT(DISTINCT salary) = 1 THEN NULL을 통해 '두 번째로 salary가 높은 사람'이 존재하지 않는 상황일 때 전부 NULL을 출력하도록 한다.
만약 이 경우가 아니라면, group by한 salary에 row_number로 순서대로 번호를 매겨 2번째 salary를 출력한다. 이게 ELSE 뒷부분의 내용이다.
그리고 아래는 Solutions에서 발견한 역대급 간단한 쿼리다.
SELECT MAX(salary) SecondHighestSalary FROM Employee
WHERE salary < (SELECT MAX(salary) FROM Employee)
놀라운 건, null에 대해 작성하지 않았다. 출력할 게 없으면 그냥 null이 나오게 한 것이다.
위 쿼리에 대한 설명을 아래 테이블을 활용해 작성해보겠다.
위와 같은 테이블이 있을 때, SELECT MAX(salary) FROM Employee, 즉 salary의 최대값은 300이다.
결국, 위 쿼리는 300 미만인 salary 중에서 최대값을 찾아달라는 뜻이고, 이 말은 두 번째 최대값을 출력해달라는 의미이다.
나는 두 번째 큰 값을 출력하려면 무조건 ORDER BY와 ROW_NUMBER을 사용해야한다고 생각했는데,
제일 큰 값보다 작은 값 중에서 최대값을 찾으면 두 번째로 큰 값을 찾을 수 있다는 것을 배웠다. (신기방기ㅎㅎ)
다음에 써먹어야지!
그리고 행이 하나거나, 행이 여러 개이지만 전부 다 같은 값인 경우, 애초에 최대값 미만인 값이 없다.
그래서 결국 NULL을 출력하게 된다.
'SQL > LeetCode' 카테고리의 다른 글
[LeetCode Medium] 550. Game Play Analysis IV(MySQL) (2) | 2023.08.28 |
---|---|
[LeetCode Medium] 180. Consecutive Numbers(Lead, Lag 함수)(MySQL) (0) | 2023.08.24 |