본문 바로가기

SQL/LeetCode&HackerRank

[MySQL] HackerRank - Top Earners 풀이 3가지

문제 출처: https://www.hackerrank.com/challenges/earnings-of-employees/problem?h_r=internal-search

문제: 가장 높은 수입과 그 금액을 버는 사람 수 찾기

 

풀이 3가지:

[1] WHERE절 서브쿼리

먼저 총 수입은 months * salary 로 구하고 earnings라고 칭한다.

가장 높은 earnings를 찾기 위해 WHERE절을 아래와 같이 작성하면 에러가 뜬다.

SELECT (months * salary) AS earnings
FROM Employee
WHERE months * salary = MAX(months * salary)

MAX() 앞에 SELECT문을 한번 더 씌우면 해결된다. 

SELECT (months * salary) AS earnings
FROM Employee
WHERE months * salary = (SELECT MAX(months * salary) FROM Employee)

여기서 months * salary가 다수 반복이 되지만

안타깝게도 SELECT에서 만든 alias(별칭)는 WHERE절에서 사용할 수 없다. (GROUP BY, ORDER BY, HAVING에서는 가능하다.)

 

여기까지하면 가장 높은 earnings 값이 n개(중복 되는 만큼) 출력된다.

이렇게

108064
108064
108064
108064
108064
108064
108064

 

여기서 이 earnings의 n개를 세려면 GROUP BY와 COUNT를 사용하면 된다.

SELECT (months * salary) AS earnings
     , COUNT(*) -- COUNT(months * salary), COUNT(employee_id)
FROM Employee
WHERE months * salary = (SELECT MAX(months * salary) FROM Employee)
GROUP BY earnings

again, SELECT문의 별칭을 WHERE절에는 못 쓰지만 GROUP BY에서는 쓸 수 있다는 것을 알 수 있다.

 

그리고 여기서 COUNT(*) 대신 COUNT(months * salary), COUNT(employee_id)를 사용해도 무방하다.

조건을 만족하는 데이터 전체(*)를 세거나, 조건을 만족하는 데이터의 (months * salary) 수를 세거나, 조건을 만족하는 employee_id를 세거나 결과 값(행의 개수)은 같기 때문이다.

 

최종 결과

108064 7

 

[2] HAVING절 서브쿼리

WHERE절 대신 HAVING절을 사용할수도 있다.

SELECT (months * salary) AS earnings
     , COUNT(*) -- COUNT(months * salary), COUNT(employee_id)
FROM Employee
GROUP BY earnings
HAVING earnings = (SELECT MAX(months * salary) FROM Employee)

차이점은 WHERE절은 GROUP BY 앞에 오지만 HAVING은 GROUP BY 뒤에 위치한다.

또 HAVING은 WHERE절과 다르게 SELECT문의 별칭을 사용할 수 있다.

 

즉, 집계함수를 사용하고 GROUP BY와 HAVING절을 함께 사용하면 WHERE절 처럼 조건을 부여할 수 있다.

 

[3] GROUP BY, ORDER BY, LIMIT

서브쿼리를 사용하지 않고도 다음과 같이 표현할 수 있다.

SELECT (months * salary) AS earnings
      , COUNT(*) -- COUNT(months * salary), COUNT(employee_id) 
FROM Employee 
GROUP BY earnings 
ORDER BY earnings DESC 
LIMIT 1

GROUP BY까지는 위에 풀이와 똑같다.

차이점은 조건이 아직 없기 때문에 GROUP BY를 했을 때 모든 earnings가 출력이 되는데,

여기서 ORDER BY earnings DESC를 적용하면 가장 높은 earnings가 최상단에 위치하게 되고

여기에 LIMIT을 1로 걸어 가장 높은 earnings만 남기면 원하는 결과를 얻게 된다. 

 

 

본 내용은 데이터리안 'SQL 데이터 분석 캠프 실전반' 을 수강하며 작성한 내용입니다.