https://www.hackerrank.com/challenges/challenges/problem?isFullScreen=true
Column | Type |
hacker_id | Integer |
name | Integer |
Hackers테이블:
- hacker_id : 해커의 id
- name : 해커의 이름
Column | Type |
challenge_id | Integer |
hacker_id | Integer |
Challenges 테이블:
- challenge_id : 챌린지의 id
- hacker_id : 해커의 id
Julia는 학생들에게 코딩 챌린지를 만들도록 요청했습니다. 각 학생이 만든 챌린지의 총 개수를 출력하는 쿼리를 작성하세요. 결과는 챌린지의 총 개수를 기준으로 내림차순으로 정렬합니다. 만약 여러 학생이 동일한 수의 챌린지를 만들었다면, hacker_id를 기준으로 정렬합니다. 여러 학생이 동일한 수의 챌린지를 만들었고 그 수가 생성된 챌린지의 최대 개수보다 적다면, 해당 학생들을 결과에서 제외합니다.
select
hacker_id,
count(challenge_id)
from Challenges c
group by hacker_id
먼저 해커별로 만든 챌린지의 수를 구해준다.
select
count_chall,
count(count_chall)
from
(select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id) a
group by count_chall
해당 쿼리를 기반으로 해서 챌린지를 만든 수가 같은 사람들의 수를 센다.
select *
from
(select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id) a
left join
(select
count_chall,
count(count_chall)
from
(select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id) a
group by count_chall) cc on a.count_chall = cc.count_chall
위의 쿼리와 작성한 챌린지의 수를 센 쿼리를 결합해서 동점자가 몇명 있는지 센다.
select
max(count_chall)
from
(select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id) a
작성한 챌린지의 최대값을 반환하는 새로운 쿼리를 작성한다.
select *
from
(
select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id
) a
left join
(
select
count_chall,
count(count_chall) ccc
from
(
select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id
) a
group by count_chall
) cc on a.count_chall = cc.count_chall
where cc.ccc = 1 or
cc.count_chall = (
select
max(count_chall)
from
(
select
hacker_id,
count(challenge_id) as count_chall
from Challenges c
group by hacker_id
) as max_chall
)
위의 동점자가 몇명인지 세는 쿼리에 where절을 추가해서 동점자가 없는 행만 출력하거나 (cc쿼리의 ccc열이 1인 행) 작성한 챌린지의 수가 최대인 행들만 출력한다. 이때 최대값은 조금 전에 작성한 최대값 쿼리를 조건으로 사용한다.
select
h.hacker_id,
h.name,
mc.count_chall
from Hackers h
inner join
(
select
a.hacker_id,
a.count_chall
from
(
select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id
) a
left join
(
select
count_chall,
count(count_chall) ccc
from
(
select
hacker_id,
count(challenge_id) count_chall
from Challenges c
group by hacker_id
) a
group by count_chall
) cc on a.count_chall = cc.count_chall
where cc.ccc = 1 or
cc.count_chall = (
select
max(count_chall)
from
(
select
hacker_id,
count(challenge_id) as count_chall
from Challenges c
group by hacker_id
) as max_chall
)
) mc on h.hacker_id = mc.hacker_id
order by mc.count_chall desc, h.hacker_id
마지막으로 이름을 출력하기 위해서 Hackers테이블과 결합하고 조건에 맞게 정렬하면 완료!
sql 코드는 길어지니까 흐름을 읽기 너무 힘든것같다... 코드를 줄여서 작성할 수 있었을까? 아니면 코드 작성을 더 깔끔하게 해서 가독성을 높여야할까?
'코딩일기' 카테고리의 다른 글
SQL 코드카타 175 - Contest Leaderboard (0) | 2024.07.27 |
---|---|
알고리즘 코드카타 118 - 거리두기 확인하기 (0) | 2024.07.26 |
알고리즘 코드카타 117 - 마법의 엘리베이터 (0) | 2024.07.25 |
SQL 코드카타 173 - Ollivander's Inventory (0) | 2024.07.25 |
알고리즘 코드카타 116 - 점찍기 (4) | 2024.07.24 |