문제
- 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
출처
반응형
'Algorithm > MySQL' 카테고리의 다른 글
[해커랭크(HackerRank)] Challenges (MySQL) (1) | 2021.07.15 |
---|---|
[LeetCode] 185. Department Top Three Salaries (MySQL) (0) | 2021.07.14 |
[LeetCode] 180. Consecutive Numbers (MySQL) (0) | 2021.07.14 |
[LeetCode] 184. Department Highest Salary (MySQL) (0) | 2021.07.14 |
[해커랭크(HackerRank)] The Report (MySQL) (0) | 2021.07.13 |