SQL/HackerRank(해커랭크)

HackerRank(해커랭크) MySQL Contest Leaderboard 문제 답

진리뷰 2023. 10. 23. 09:00
반응형

 

 

HackerRank(해커랭크)-MySQL-contest-leaderboard-문제-답-썸네일
Contest Leaderboard

 

 

*MySQL 버전, Basic Join 문제입니다.

 

 

 

해커랭크 Contest Leaderboard 문제, 설명

 

💡hacker_id, name, total score 가져오기

  • total score = 모든 챌린지들 점수 중 최고점 총합
  • total score 내림차순, hacker_id 오름차순 정렬
  • total score = 0은 제외

 

해커랭크-contestleaderboard-문제
Contest Leaderboard 문제

 

 

해커랭크-contestleaderboard-테이블1해커랭크-contestleaderboard-테이블2
Contest Leaderboard 테이블

 

 

 

해커랭크 Contest Leaderboard 답

 

💡서브쿼리 JOIN

조건을 건 테이블도 JOIN 가능하다.

SELECT hacker_id
, name
, SUM(b.s_max) AS s_total
FROM hackers

JOIN (
SELECT hacker_id
, challenge_id
, MAX(score) AS s_max
FROM submissions
GROUP BY 1, 2
) AS b
ON a.hacker_id = b.hacker_id

GROUP BY 1, 2
HAVING SUM(b.s_max) > 0

ORDER BY 3 DESC, 2;

 


 

JOIN 한 b 테이블은 다음과 같다.

이는 결과물을 제출한 hacker_id, challenge_id를 기준으로 나열하고 각 제출물의 최고점을 가져오는 쿼리다.

SELECT hacker_id
, challenge_id
MAX(score) AS s_max
FROM submissions
GROUP BY 1, 2;

 

한 명의 해커가 챌린지마다 여러 개 제출할 수 있다. 즉,  hacker_id는 한 개지만 그의 challenge_id는 여러 개일 수 있다.

만약 여러 challenge_id가 있다면, 각 challenge_id 별 최고점이 반환되지만 결국은 한 해커의 점수들이다.

*hacker_id = 486, 1700의 challenge_id는 두 개이며, 각각의 최고점이 반환되었다.

최고점 쿼리 결과

 

 

그러나 최종적으로 가져와야 하는 것은 hacker_id, name, total score이다.

때문에 name이 있는 hackers 테이블이 필요하다. 

따라서 submissions 테이블에서 구한 값들이 담긴 위 쿼리를 name이 있는 hackers 테이블에 JOIN 한다.

FROM hackers
JOIN (
SELECT hacker_id
, challenge_id
, MAX(score) AS s_max
FROM submissions
GROUP BY 1, 2
) AS b
ON a.hacker_id = b.hacker_id

 

total score는 위 쿼리에서 구한 해커의 최고점들을 모두 더한 것이다.

그러므로 SELECT에 sum을 사용하면 된다.

SELECT hacker_id
, name
, SUM(b.s_max) AS s_total
FROM hackers

JOIN (
SELECT hacker_id
, challenge_id
, MAX(score) AS s_max
FROM submissions
GROUP BY 1, 2
) AS b
ON a.hacker_id = b.hacker_id

 

마지막으로 total score=0은 제외해야 하는 조건과 정렬 기준이 있다.

이때 total score는 집계함수 sum을 사용했으므로 GROUP BY를 지정하고 HAVING으로 조건을 명시한다.

SELECT hacker_id
, name
, SUM(b.s_max) AS s_total
FROM hackers

JOIN (
SELECT hacker_id
, challenge_id
, MAX(score) AS s_max
FROM submissions
GROUP BY 1, 2
) AS b
ON a.hacker_id = b.hacker_id

GROUP BY 1, 2
HAVING SUM(b.s_max) > 0

ORDER BY 3 DESC, 2;

 

 

 

추가 정리

 

💡서브쿼리

  • 조건 여러 개일 때, 여러 SELECT(=서브쿼리) 사용.
  • 다른 테이블들의 데이터에 조건을 걸어 JOIN 가능.

💡HAVING

  • 그룹 함수/집계 함수에 조건 걸 때 사용 (집계 함수 아닐 때 조건 걸고 싶으면 WHERE)

 

반응형
top