안녕하세요. 오늘도 SQL 문제를 풀고 있습니다.
일부 막히는 부분이 있어 고민하다가 결국 풀이를 봤네요...
도대체 언제쯤 풀이를 보지 않고 풀 수 있을까..
문제의 요구사항은 다음과 같습니다.
- hackers 테이블과 challenges 테이블이 존재합니다.
- hackers 테이블에는 hacker_id, name 칼럼이 존재하며 challenges 테이블에는 hacker_id, challenge_id가 존재합니다.
- 가장 많이 도전했던 hacker_id 순으로 출력하며 출력 데이터는 hacker_id, name, 도전했던 수입니다.
- 도전했던 수가 동일하다면 hacker_id를 오름차순으로 정렬합니다.
- 만약 도전했던 수가 동일한 hacker들이 존재하며 최고 도전했던 수보다 작을경우 해당 hacker들은 출력 데이터에서 제외시킵니다.
hackers 테이블
hacker_id | name |
12299 | Rose |
34856 | Angela |
79345 | Frank |
80491 | Patrick |
81041 | Lisa |
challenges 테이블
challenge_id | hacker_id |
63963 | 81041 |
63117 | 79345 |
28225 | 34856 |
21989 | 12299 |
4653 | 12299 |
70070 | 79345 |
36905 | 34856 |
61136 | 80491 |
17234 | 12299 |
hacker_id | name | challenges_created |
12299 | Rose | 6 |
34856 | Angela | 4 |
79345 | Frank | 4 |
80491 | Patrick | 3 |
81041 | Lisa | 1 |
출력 예제
12299 Rose 6
80491 Patrick 3
81041 Lisa 1
풀이)
SELECT C2.hacker_id, H.name, C2.challenges_created FROM hackers H
inner join (
SELECT C.hacker_id, count(challenge_id) as challenges_created FROM Challenges C
GROUP BY C.hacker_id
HAVING
challenges_created IN
(
SELECT C1.total FROM (
SELECT hacker_id, count(challenge_id) as total FROM Challenges
GROUP BY hacker_id) C1
GROUP BY C1.total
HAVING count(hacker_id) = 1
)
OR
challenges_created =
(SELECT count(DISTINCT challenge_id) as challenges_created FROM Challenges
GROUP BY hacker_id ORDER BY challenges_created DESC LIMIT 1)) C2
ON C2.hacker_id = H.hacker_id
ORDER BY C2.challenges_created DESC, C2.hacker_id
최고 도전수보다 작으며 중복된 도전 수를 가진 해커들을 찾는게 이 문제의 핵심입니다.
SELECT C1.total FROM (
SELECT hacker_id, count(challenge_id) as total FROM Challenges
GROUP BY hacker_id) C1
GROUP BY C1.total
HAVING count(hacker_id) = 1
1. 해커별로 그룹핑하여 해커별 도전 수를 구합니다.
2. 해커별 도전수 테이블을 인라인 뷰로 활용하여 이번에는 도전수 별로 그룹핑합니다.
3. 도전수 별 해커 수가 1인 즉, 중복되지 않은 도전수를 구합니다.
출처
'DB' 카테고리의 다른 글
Real My SQL - 아키텍처(1) (0) | 2021.06.06 |
---|---|
SQL 문제풀이 6) (0) | 2020.12.20 |
SQL 문제풀이 4) (0) | 2020.12.18 |
SQL 문제풀이 3) (0) | 2020.12.17 |
SQL 문제풀이 2) (0) | 2020.12.16 |