반응형
문제
https://www.hackerrank.com/challenges/challenges/problem?h_r=internal-search
문제가 길다보니 링크로 대체하겠다.
문제 풀이
SELECT hackers.hacker_id,
hackers.name,
COUNT(*) AS challenges_created
FROM Challenges
INNER JOIN hackers ON Challenges.hacker_id = Hackers.hacker_id
GROUP BY hackers.hacker_id, hackers.name
HAVING challenges_created = (SELECT MAX(challenges_created)
FROM(
SELECT hacker_id,
COUNT(*) AS challenges_created
FROM Challenges
GROUP BY hacker_id
) sub)
OR challenges_created IN (SELECT challenges_created
FROM(
SELECT hacker_id,
COUNT(*) AS challenges_created
FROM Challenges
GROUP BY hacker_id
) sub
GROUP BY challenges_created
HAVING COUNT(*) = 1)
ORDER BY challenges_created DESC , hacker_id
문제 해설
상당히 어렵고 힘들었던 문제였다. 이 문제 또한 영상강의를 참고하여 문제 풀이가 진행됐다. 먼저 문제를 다단계적으로 접근하면 이렇다.
- Hackers테이블과 Challenges테이블의 공통 column값인 hacker_id로 테이블을 병합한다.
- 병합한 table을 바탕으로 hacker_id의 갯수를 counting한다.
- counting한 값과 hacker_id를 바탕으로 counting한 값은 내림차순, hacker_id는 오름차순을 진행한다.
- 정렬이 된 테이블중에 counting 한 값(challenges_created)이 해당 테이블의 Max값이면 지우지않고 놔둔다.
- 정렬이 된 테이블중 challenges_created이 Max값이 아니면서 2개 이상 있으면 중복된 값들은 전부 지운다.
이 순서로 문제 접근이 진행됐다.
따라서 subquery와 Inner join, Group by, having, order by 등 다양한 문법들을 사용하였다.
처음엔
SELECT hackers.hacker_id,
hackers.name,
COUNT(*) AS challenges_created
FROM Challenges
INNER JOIN hackers ON Challenges.hacker_id = Hackers.hacker_id
GROUP BY hackers.hacker_id, hackers.name
ORDER BY challenges_created DESC , hacker_id
해당 쿼리문으로 1,2,3번 단계를 밟았다.
4,5번이 상당히 골치 아팠는데 서브쿼리를 이용하여 중복을 체크하는 것이 아닌, 중복이 안돼서 갯수가 1인 값들만 가져오는 방법을 선택했다.
Where문은 집계함수가 사용이 불가능하여 Having절을 사용하였고 처음엔 max값만 찾는것이니 = 을 사용했지만 값이 여러개를 확인해야 하므로 IN을 사용하였다.
HAVING challenges_created = (SELECT MAX(challenges_created)
FROM(
SELECT hacker_id,
COUNT(*) AS challenges_created
FROM Challenges
GROUP BY hacker_id
) sub)
OR challenges_created IN (SELECT challenges_created
FROM(
SELECT hacker_id,
COUNT(*) AS challenges_created
FROM Challenges
GROUP BY hacker_id
) sub
GROUP BY challenges_created
HAVING COUNT(*) = 1)
해당 코드에서
SELECT MAX(challenges_created)
FROM(
SELECT hacker_id,
COUNT(*) AS challenges_created
FROM Challenges
GROUP BY hacker_id
) sub
이러한 쿼리문이 많이 사용되어 코드 가독성 및 작성에 불편을 느낄 수 있다.
이를 해결하고자 with문을 작성하는 방법이 있는데 이는 다음 글에서 설명하겠다.
'SQL > MySQL' 카테고리의 다른 글
[MySQL] 조인조건이 특이한 문제 풀어보기 (Hacker Rank - The Report )풀어보기 (0) | 2022.02.23 |
---|---|
[MySQL] with 절 사용 법 및 예제 (0) | 2022.02.16 |
[MySQL] 서브쿼리 해커랭크(Top Earners), 리트코드(Department Highest Salary) 예제문제 풀어보기 (0) | 2022.02.14 |
[MySQL] 서브쿼리 ( Subquery) (0) | 2022.02.14 |
[MySQL] DML (Data Manipulation Language) 예제 문제 풀어보기 with LeetCode (0) | 2022.02.06 |