SQL - Mysql & Oracle/SQL 실전 코딩 테스트
[MySQL] Hackerrank - Challenges 문제 풀이 및 해설
BK_Paul
2023. 11. 23. 10:41
반응형
오늘 풀어보면서 공부할 문제는 Hackerrank에서 출제한 SQL Project Planning이다. 이 문제를 풀 때 개인적으로 Exists문을 통해서 풀어 냈고, 이 과정에서 배운 것을 공유하고자 한다.
목차
1. 문제 출처 및 소개
2. MAX와 IN을 이용한 문제 풀이
3. Lesson Learned
1. 문제 출처 및 소개
- 문제의 출처: URL
- 문제의 요구 조건 정리
- Hacker의 ID, 이름 그리고 각자 만든 문제 수를 호출하는 것
- 정렬 순서는 문제 수 기준 내림차순과 hacker id기준으로 오름차순으로 정리
- 문제의 특이사항 정리
- 만약에 중복된 문제 개수가 있다면 제외할 것
- 단, 그 중복된 문제 개수가 최대값과 일치한다면 제외시키지 말 것
이 문제의 핵심은 문제 풀이 수를 기준으로 예외 처리를 해서 정답을 내는 것에 있다. 이 문제는 기본적으로 MAX, IN, 그리고 Self JOIN을 통해서 해결해나갈 수 있다.
2. Exists문을 통한 문제 풀이
문제 풀이 전략은 우선 문제 풀이 수를 ID별로 지정을 한 다음에, WHERE 절에서 문제의 요구사항을 만족하는데 있다. 따라서 base라는 subquery를 우선 말아두고, WHERE에서 MAX와 IN을 통해 해결해나갈 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
with base as (
SELECT a.hacker_id
, COUNT(DISTINCT a.challenge_id) as c_cnt
FROM Challenges a
GROUP BY a.hacker_id
)
SELECT t1.hacker_id
, t2.name
, t1.c_cnt
FROM base t1
JOIN Hackers t2 on t2.hacker_id = t1.hacker_id
WHERE 1 = 1
and (
t1.c_cnt = (SELECT MAX(d1.c_cnt) FROM base d1 )
or
t1.c_cnt NOT IN (
SELECT d2.c_cnt
FROM base d2
GROUP BY d2.c_cnt HAVING COUNT(DISTINCT d2.hacker_id) >= 2
)
)
ORDER BY t1.c_cnt DESC, t1.hacker_id ASC
|
cs |
- 문제 풀이 공략
- Step1. Hacker ID별로 만든 문제 수를 계산한다.
- Subquery에서 이를 수행했고, COUNT DISTINCT 로직을 통해서 계산했다.
- 이렇게 되면 우리가 다루어야 할 숫자는 모두 만든 상태이다.
- Step2. MAX를 통해서 최대값을 가져온다.
- SELF JOIN을 하는 방법이 여러개가 있지만, 여기서는 정수하나만 가져오면 되기 때문에 WHERE 절에서 바로 다루었다.
- Step3. IN을 통해 원하는 숫자를 가져온다.
- SELF JOIN하는 방법은 위와 동일하다.
- 그 중에서 GROUP BY ~ HAVING ~을 통해서 중복되는 숫자를 모두 제거한다.
- 또한 위의 Step과 병렬로 조건이 처리되어야 하기 때문에 OR로 묶어두었다.
- Step1. Hacker ID별로 만든 문제 수를 계산한다.
3. Lesson Learned
이 문제는 개인적으로 많은 주제에 대해서 공부를 할 수 있었다. 그 중에서 다른 문제 풀이에도 활용할 수 있을만한 주제에 대해서 간단히 오답노트를 기록하고 공유하도록 하겠다.
✅ WHERE 절에서 SELF JOIN을 하는 방법
이 문제는 정수 처리를 어떻게 하는가에 따라 당락이 나뉜다. JOIN을 통해서 해도 되지만, WHERE절에서 수행하게 되면 보다 디테일하게 정수 처리를 할 수 있는 방법을 배웠다. 하지만 반대로 여러 번 JOIN을 걸다보니 시공간 복잡도에서는 좋은 방법이 아니라는 단점도 존재한다.
반응형