문제 이해
Hackers, Challenges 테이블에서 해커 아이디, 이름, 만든 문제 수를 가져와야 한다.
이 때, 문제 수의 내림차순으로 정렬하고, 문제 수가 같다면 해커 아이디의 오름차순으로 정렬한다.
만약 만든 문제 수가 최대가 아니면서 두 명 이상이 같은 수의 문제를 만들었을 경우 결과에서 제외한다.
예를 들어, A가 7개, B가 6개, C가 6개, D가 7개의 문제를 만들었다고 하자. 최대 문제 수는 7인데, B와 C가 똑같이 6개씩 문제를 만들었다. 이 경우 B와 C를 결과에서 제외한다는 뜻이다. A와 D는 최대 문제 수인 7개를 만들었으므로 둘 다 결과에 포함한다.

hacker_id : 해커의 아이디
name : 해커의 이름

challenge_id : 문제의 아이디
hacker_id : 문제를 만든 해커의 아이디
풀이 설명
(1)최대 문제 수를 구하는 부분과, (2)최대가 아니면서 단 한 사람만이 그러한 개수의 문제를 만든 경우를 구하는 두 부분으로 나누어 해결한다.
우선 메인 쿼리는 다음과 같다.
select h.hacker_id, h.name, count(*) as no_challenges
from hackers h
inner join challenges c
on h.hacker_id = c.hacker_id
group by h.hacker_id, h.name
order by no_challenges desc, h.hacker_id asc;
이대로라면 모든 해커의 아이디, 이름과 만든 문제 수를 가져온다.
1. 여기서 no_challenges가 최대인 것만 남긴다.
최대 문제 수를 구하려면
1) Challenges 테이블에서 hacker_id로 그룹짓고
2) 문제 수의 내림차순으로 정렬한 뒤
3) 가장 큰 하나만 남긴다.
문제 수의 내림차순으로 정렬은 group by count(*) desc로, 가장 큰 하나는 limit 1로 구한다. 쿼리는 아래와 같다.
select count(*)
from challenges
group by hacker_id
order by count(*) desc
limit 1;
그리고 구한 count(*) (최대 문제 수)가 메인 쿼리의 no_challenges와 같은지 확인하면 된다.
2. 만약 no_challenges가 최대가 아니라면, 어떤 no_challenges 값을 단 한 사람만이 가지고 있는 경우만 남긴다.
이를 구하려면
1) 위와 같이, Challenges 테이블에서 hacker_id별 문제 수를 구한다.
2) 1)에서 구한 결과에서 어떤 no_challenges값을 단 한 사람만이 갖는 경우를 찾는다.
쿼리 중첩이 필요하다.
select other_count
from (select count(*) as other_count
from challenges
group by hacker_id) as temp
group by other_count
having count(other_count) = 1
안쪽 쿼리에서 해커 별 만든 문제수를 other_count로 구했고, 바깥 쿼리에서 그 other_count의 값으로 그룹을 지은 뒤, other_count의 개수가 1인 경우만 남겼다. 그리고 메인 쿼리의 no_challenges가 여기서 구한 결과에 존재하는지 확인하면 된다.
이것을 모두 합치면 아래의 쿼리가 된다.
구현
select h.hacker_id, h.name, count(*) as no_challenges
from hackers h
inner join challenges c
on h.hacker_id = c.hacker_id
group by h.hacker_id, h.name
having no_challenges = (select count(*)
from challenges
group by hacker_id
order by count(*) desc
limit 1)
or no_challenges in (select other_count
from (select count(*) as other_count
from challenges
group by hacker_id) as temp
group by other_count
having count(other_count) = 1)
order by no_challenges desc, h.hacker_id asc;
오류가 있었던 부분
1. SQL operation의 순서는 SELECT -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY다.
2. Aggregate function COUNT()를 사용하고 있으므로 WHERE가 아닌 HAVING으로 조건을 명시해 주어야 한다.
3. OR no_challenges IN (SELECT ~ 쿼리에서 FROM 뒤에 오는 쿼리에 ALIAS를 줘야 에러가 나지 않았다.
'SQL' 카테고리의 다른 글
HackerRank Ollivander's Inventory (0) | 2021.03.02 |
---|