skip to Main Content

https://www.hackerrank.com/challenges/contest-leaderboard/problem?isFullScreen=true

The total score of a hacker is the sum of their maximum scores for all of the challenges. Write a query to print the hacker_id, name, and total score of the hackers ordered by the descending score. If more than one hacker achieved the same total score, then sort the result by ascending hacker_id. Exclude all hackers with a total score of 0 from your result.

The following tables contain contest data:

Hackers: The hacker_id is the id of the hacker, and name is the name of the hacker.

Submissions: The submission_id is the id of the submission, hacker_id is the id of the hacker who made the submission, challenge_id is the id of the challenge for which the submission belongs to, and score is the score of the submission.

I was trying to solve this hackerrank problem and I can’t figure out what mistake am I making.

select h.hacker_id,h.name,sum(s.score) as total
from hackers as h inner join submissions as s on h.hacker_id=s.hacker_id
group by h.hacker_id,h.name
having total in
(
    select sum(max(score))
    from 
    (   select max(score)
        from submissions
        group by hacker_id,challenge_id
    )as highest
    group by hacker_id
    having sum(total)<>0
)
order by sum(s.score),h.hacker_id;

Any help would be highly appreciated.

2

Answers


  1. The original query contained several inconsistencies, notably in the use of the HAVING clause with SUM and MAX. Use a LEFT JOIN to ensure that all hackers from the "Hackers" table are included in the results, even if they haven’t submitted solutions. Then, use a subquery to obtain the maximum score for each (hacker_id, challenge_id) pair. Finally, group the results by hacker_id and name, calculate the sum of the maximum scores (total_score), exclude hackers with a total_score of 0, and then order the result by total_score in descending order, followed by hacker_id in ascending order in case of a tie in total_score.

    SELECT h.hacker_id, h.name, COALESCE(SUM(s.score), 0) AS total_score
    FROM Hackers h
    LEFT JOIN (
        SELECT hacker_id, challenge_id, MAX(score) AS score
        FROM Submissions
        GROUP BY hacker_id, challenge_id
    ) s ON h.hacker_id = s.hacker_id
    GROUP BY h.hacker_id, h.name
    HAVING total_score <> 0
    ORDER BY total_score DESC, h.hacker_id;
    
    Login or Signup to reply.
  2. total comes from the select in the outer query, so you couldn’t use it in the having, nor does it make sense to use it again in the inner having.

    You also can’t use sum(max(score)). I suspect you actually meant to use a column alias on the innermost query and then refer to it again in the intermediate level.

    Either way, this doesn’t look right. There is no need for the extra self-join on submission, you can do it in without that. You just need to pre-aggregate the max scores, then join it.

    select
      h.hacker_id,
      h.name,
      s.total
    from hackers as h
    join (
        select
          s.hacker_id,
          sum(s.max_score) as total
        from 
        (
            select
              s.hacker_id,
              max(s.score) as max_score
            from submissions as s
            group by
              s.hacker_id,
              s.challenge_id
        ) as s
        group by
          s.hacker_id
        having sum(s.max_score) > 0
    ) as s on s.hacker_id = h.hacker_id
    order by
      s.total desc,
      h.hacker_id;
    

    You can also do it in just two levels, but then you need to go back to aggregating on hacker_id, which may be inefficient.

    select
      h.hacker_id,
      h.name,
      sum(s.max_score) as total
    from hackers as h
    join (
        select
          s.hacker_id,
          max(s.score) as max_score
        from submissions as s
        group by
          s.hacker_id,
          s.challenge_id
    ) as s on s.hacker_id = h.hacker_id
    group by
      h.hacker_id,
      h.name
    having sum(s.max_score) > 0
    order by
      s.total desc,
      h.hacker_id;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search