[mySQL] 해커랭크 Top Earners 문제를 이해하기 위한 고군분투

sehyunny·2023년 4월 11일
0

mySQL

목록 보기
2/26

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

문제에서 알려준 것 : 총 소득 = 월급 x 근무개월

  1. Maximum total earnings를 밝히고
  2. Maximum total earnings를 받는 사원이 몇명인지 구하기

내가 시도했다가 실패한 코드들

SELECT MAX(salary * months), count(MAX(salary * months)
FROM employee

아주 괴상한 코드....
단순히
1. salary * months의 최고값을 구하라길래 MAX함수를 썼고
2. 그리고 그냥 그걸 세달라고 함....
코드 안돌아감. 당연함. 해당 테이블에는 salary * months라는 컬럼이 없음

다른 코드로 도전

SELECT salary * months
FROM employee
ORDER BY salary * months DESC

위를 통해 최대값이 108064인것을 알아내서 아래처럼 작성해봄

SELECT salary * months, COUNT(salary * months = 108064)
FROM employee
ORDER BY salary * months DESC

또 안됨.
당연함. 애초에 저 테이블에는 salary * months라는 컬럼도, 그 값을 가진 컬럼도 없음.

그래서 일단 테이블 구조를 봄

SELECT *
FROM employee

음.. 그러면 일단 salary * months의 값을 봐야겠다 싶었음

SELECT salary * months
FROM employee

곱한 값이 중복되어 나왔기 때문에 GROUP BY를 사용해서 그루핑 해주었다

SELECT salary * months
FROM employee
GROUP BY salary * months

중복값을 제거했으나 여전히 '각 토탈값에 몇 명씩 있는지'는 알 수 없었다..
이걸 어떻게 알아내야 할까.......

SELECT salary * months, COUNT(salary * months)
FROM employee
GROUP BY salary * months

위 코드를 돌렸더니 '각 토탈값 + 몇명씩 있는지'를 알 수 있었다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠ

그 다음부턴 아주 쉬웠다.. ORDER BY를 통해 내림차순 정렬해주고, LIMIT을 통해 최대값만 출력

SELECT salary * months, COUNT(salary * months)
FROM employee
GROUP BY salary * months
ORDER BY salary * months DESC
LIMIT 1

왜 못풀었는가를 생각해보니
1. 왜 GROUP BY를 해야하는지 이해가 안갔음.
GROUP BY를 하면 똑같은 값을 하나로 묶어준다는 개념에 대한 이해가 부족한 거 같아서 강의를 다시 봤다.
2. 토탈값에 몇 명이 있는지 = 토탈값이 총 몇 번 중복되는지'라는 것을 이해하지 못함
COUNT(salary * months)를 통해 salary * months의 값에 몇 개의 데이터들이 중복되는지 알아냄....
ex. salary * months가 100이었다면, COUNT(salary * months)는 즉 '곱한 값이 100인 행의 개수를 세어라 = 곱한 값이 100인 사람의 수를 세어라'였다!!!

강의를 다시 들어보니 강사님의 코드는 나와 다른 것 같아서 추가로 정리해보자면,

문제풀이 순서
1. salary * momnths = earnings 구하기
2. 각 earnings 별로 몇 명이 그만큼 벌었는지를 계산 ex. (5000, 2 / 3000, 5) GROUP BY
3. earning 중에 가장 큰 값을 가져온다 ORDER BY, LIMIT

SELECT salary * months AS earnings
FROM employee
SELECT salary * months AS earnings
      ,COUNT(*)
FROM employee
GROUP BY earnings

여기서 왜 COUNT(*)인지 알 수 없어서 고민을 또 한참 했다..
왜지? 왜 COUNT(salary * months)가 아니라 COUNT(*)인거지? 계속 생각했는데

답은.. 
GROUP BY earnings를 해주어서 각 값이 그루핑 되어있을 거고 (중복인거 다 무시하고 1개씩 출력되고 있음)
그리고 그 행이 몇개인지만 세어주면 되니까 COUNT(*)로 써줘도 상관 없는 거였음

earnings 중 가장 큰 값 1개만 출력

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

선생님과 내 코드를 비교 해보기로 했다.

내가 작성한 코드

SELECT salary * months, COUNT(salary * months)
FROM employee
GROUP BY salary * months
ORDER BY salary * months DESC
LIMIT 1

선생님께서 작성하신 코드

SELECT salary * months AS earnings
      ,COUNT(*)
FROM employee
GROUP BY earnings
ORDER BY earnings DESC
LIMIT 1
  1. COUNT(salary * months)라고 써줄 건지, COUNT(*)라고 쓸건지
    이건 내가 ORDER BY (salary * months)를 하면 그루핑 되니까
    그 행만 몇개인지 세어주면 된다는 거에 대한 이해를 못했어서 차이가 생긴걸로 보인다! 지금은 이해함!

  2. 나는 계속 salary * months라고 썼는데, 선생님은 알리아스를 활용 해서 보기 쉽게 함
    나는 아직 AS를 쓰는 것에 익숙해지지 않은 것 같다 ㅠㅠ

아직 2주차밖에 안됐지만 풀이 과정을 보고서도 이해가 안간 건 이 문제가 처음이었다..
너무 답답해서 이것만 계속 붙들고 매달렸다 ㅠㅠ

단순히 코드를 짜는게 문제가 아니라
왜 그렇게 짜는지를 이해하고 나니깐 속이 다 시원하다.....휴

앞으로도 이렇게 끈기있게 문제 풀어야지

0개의 댓글