문제 출처: 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 데이터 분석 캠프 실전반' 을 수강하며 작성한 내용입니다.
'SQL > LeetCode&HackerRank' 카테고리의 다른 글
[MySQL] HackerRank - Challenges 풀이 (0) | 2023.03.23 |
---|---|
[MySQL] LeetCode 184 - 서브쿼리와 이너 조인 활용하기 (0) | 2023.01.05 |
[MySQL] Leetcode 196 - DELETE문을 사용하여 중복값 삭제하기 (1) | 2022.12.21 |
[MySQL] Leetcode 627 - UDATE문을 사용하여 성별 전환하기 (0) | 2022.12.19 |
[MySQL] DATE_FORMAT 함수로 날짜 형식 변경하기 (2) | 2022.12.11 |