MySQL 해커랭크 | Interviews (해커랭크 Hard 문제풀이)

    728x90

     

    문제

    https://www.hackerrank.com/challenges/interviews/problem?isFullScreen=true

     

    Interviews | HackerRank

    find total number of view, total number of unique views, total number of submissions and total number of accepted submissions.

    www.hackerrank.com

    • Write a query to print the contest_id, hacker_id, name, and the sums of total_submissions, total_accepted_submissions, total_views, and total_unique_views for each contest sorted by contest_id.
    • Exclude the contest from the result if all four sums are 0.
    • A specific contest can be used to screen candidates at more than one college, but each college only holds 1 screening contest.

     

    테이블

    Contests Colleges Challenges

    • hacker_id is the id of the hacker
       who created the contest
    Submission_Stats  View_Stats

     

    풀이과정

    # Submission_Stats 테이블에 같은 challenge_id가 여럿인 이유?

    왜 같은 challenge_id가 하나로 합쳐지지 않고, 다른 행에 존재하는 걸까?

    예를 들어 challnge_id가 47127인 행이 3개나 있음

    (View_Stats 테이블의 상황도 마찬가지임. 같은 challenge_id가 여러 행에 있음)

     

    → 이유를 알기 위해 Challenges 테이블, Colleges 테이블, Contests 테이블을 모두 조인해봄

    1
    2
    3
    4
    5
    6
    SELECT ct.hacker_id, cl.contest_id, ch.college_id, ch.challenge_id, ss.total_submissions, ss.total_accepted_submissions
    FROM Submission_Stats ss
    JOIN Challenges ch ON ch.challenge_id = ss.challenge_id
    JOIN Colleges cl ON cl.college_id = ch.college_id
    JOIN Contests ct ON ct.contest_id = cl.contest_id
    ORDER BY 2
    cs
    hacker_id contest_id college_id challenge_id total
    _submissions
    total_accepted
    _submissions


     차례대로 hacker_id, contest_id, college_id, challenge_id, ...

     

    ▶ 이 결과에서 알 수 있는 사실

    • 한 hacker마다 하나의 contest를 개최함
    • 한 contest에 다양한 colleges가 참여함
    • 한 college가 여러 challenge에 참여함

     

    # Submission_Stats 테이블에 있는 challenge_id와 View_Stats에 있는 challenge_id의 양상이 다름!

    challenge_id가 47127인 경우가

    Submission_Stats 테이블에는 3개 행에 등장하고, View_Stats 테이블에는 2개 행에만 등장함

    즉, 두 테이블의 조인에 유의해야 함!

    → 두 테이블 각각에서 각 contest 별로 우리가 구하고자 하는
    total_submissions, total_accepted_submissions, total_views, and total_unique_views 의 합계를 구해줘야 함

    • Submission_Stats 테이블 : SUM( total_submissions ), SUM( total_accepted_submissions )
    • View_Stats 테이블 :  SUM( total_views ), SUM( total_unique_views )
    1
    2
    3
    4
    5
    6
    7
    # Submission_Stats
    SELECT ct.contest_id, ct.hacker_id, ct.name, SUM(ss.total_submissions) ts, SUM(ss.total_accepted_submissions) tas
    FROM Submission_Stats ss
    JOIN Challenges ch ON ch.challenge_id = ss.challenge_id 
    JOIN Colleges cl ON cl.college_id = ch.college_id
    JOIN Contests ct ON ct.contest_id = cl.contest_id
    GROUP BY 1,2,3
    cs
    1
    2
    3
    4
    5
    6
    7
    # View_Stats
    SELECT ct.contest_id, ct.hacker_id, ct.name,  SUM(vs.total_views) tv, SUM(vs.total_unique_views) tuv
     FROM View_Stats vs
    JOIN Challenges ch ON ch.challenge_id = vs.challenge_id 
    JOIN Colleges cl ON cl.college_id = ch.college_id
    JOIN Contests ct ON ct.contest_id = cl.contest_id
    GROUP BY 1,2,3
    cs

     

     

    # 정답

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SELECT a.contest_id, a.hacker_id, a.name, a.ts, a.tas, b.tv, b.tuv
    FROM
    SELECT ct.contest_id, ct.hacker_id, ct.name, SUM(ss.total_submissions) ts, SUM(ss.total_accepted_submissions) tas
    FROM Submission_Stats ss
    JOIN Challenges ch ON ch.challenge_id = ss.challenge_id 
    JOIN Colleges cl ON cl.college_id = ch.college_id
    JOIN Contests ct ON ct.contest_id = cl.contest_id
    GROUP BY 1,2,3 ) a
    LEFT JOIN
    SELECT ct.contest_id, ct.hacker_id, ct.name,  SUM(vs.total_views) tv, SUM(vs.total_unique_views) tuv
     FROM View_Stats vs
    JOIN Challenges ch ON ch.challenge_id = vs.challenge_id 
    JOIN Colleges cl ON cl.college_id = ch.college_id
    JOIN Contests ct ON ct.contest_id = cl.contest_id
    GROUP BY 1,2,3 ) b ON a.contest_id = b.contest_id AND a.hacker_id = b.hacker_id AND a.name = b.name
    WHERE ts + tas + tv + tuv != 0
    ORDER BY 1
    cs

     

    배운점

    테이블이 여러 개 있을 때 같은 컬럼이 보인다고 신나서 무작정 조인할 게 아니라

    그 관계성을 살펴본 뒤 신중하게 해야한다..!

     

    처음에 Submissions_Stats 테이블과 View_Stats 테이블을 일단 냅다 조인한 뒤 나머지 행들을 SUM 해주고나서

    왜 오답이 나오는지 모르겠다고 하고 있었으니..

    아직도 테이블의 관계성, 구조를 보는 눈이 많이 부족하다.

    728x90

    댓글