HackerRank Challenges Solution
Going back to the problem
Clarifying the Objective
Objective: Select hackers based on the following criteria:
- Maximum Challenge Solvers: Hackers who have solved the highest number of challenges, regardless of ties.
- Unique Challenge Solvers: Hackers who have solved a unique number of challenges compared to others, being the only ones with that specific count.
Example Scenario:
- Hackers A and B each solved 7 challenges, the maximum number.
- Hackers D and E are tied with 5 challenges each.
- Hacker F solved 3 challenges, a unique count no other hacker has achieved.
Expected Outcome:
- Include Hackers A, B (for solving the maximum challenges) and F (for a unique challenge count).
- Exclude Hackers D and E; their count isn’t maximum or unique.
Summary: The query aims to identify hackers who are either at the top in challenge count or have a unique count not shared with others.
Approach
To select hackers who have solved either the maximum or a unique number of challenges, we break down the query into steps:
- Calculate the number of challenges solved by each hacker.
- Determine the maximum number of challenges solved by any hacker.
- Find challenge counts unique to individual hackers.
- Select hackers who meet either of the above criteria.
SQL Query Breakdown:
- RankedHackers CTE: Calculates challenges solved by each hacker.
- MaxChallenges CTE: Finds the maximum number of challenges solved.
- UniqueChallenges CTE: Identifies unique challenge counts.
- Final SELECT: Uses LEFT JOIN to filter hackers based on criteria.
SQL Code using CTE (Common Table Expressions)
-- Calculate the number of challenges solved by each hacker
WITH ChallengeCounts AS (
SELECT
h.hacker_id,
h.name,
COUNT(DISTINCT c.challenge_id) AS challengesCount
FROM
Challenges c
JOIN
Hackers h ON c.hacker_id = h.hacker_id
GROUP BY
h.hacker_id, h.name
),
-- Determine the maximum number of challenges solved by any hacker
MaxChallengeCount AS (
SELECT
MAX(challengesCount) AS maxChallenges
FROM
ChallengeCounts
),
-- Find the counts of challenges that are unique to individual hackers
UniqueChallengeCounts AS (
SELECT
challengesCount
FROM
ChallengeCounts
GROUP BY
challengesCount
HAVING
COUNT(*) = 1
)
-- Select hackers who have either solved the maximum number of challenges
-- or have a unique challenge count
SELECT
cc.hacker_id,
cc.name,
cc.challengesCount
FROM
ChallengeCounts cc
WHERE
cc.challengesCount IN (SELECT maxChallenges FROM MaxChallengeCount)
OR cc.challengesCount IN (SELECT challengesCount FROM UniqueChallengeCounts)
ORDER BY
cc.challengesCount DESC, cc.hacker_id;
SQL Code using Subquery Approach
For compatibility with older versions of MySQL where Common Table Expressions (CTEs) are not supported, an alternative approach using subqueries in the FROM and WHERE clauses can be employed.
Approach
- Joining and Grouping:
- Join the
Challenges
andHackers
tables. - Group the results by hacker to calculate each hacker’s challenge count.
- Join the
- Applying Conditions with HAVING:
- Use the
HAVING
clause to filter results based on two conditions:- The hacker’s challenge count matches the maximum number of challenges solved. This is determined by a subquery (
SubMax
) calculating the maximum challenge count across all hackers. - The hacker’s challenge count is unique, ascertained by another subquery (
SubUnique
). This subquery calculates challenge counts for all hackers and groups them to identify counts that only appear once.
- The hacker’s challenge count matches the maximum number of challenges solved. This is determined by a subquery (
- Use the
- Ordering Results:
- Order the results by challenge count in descending order, followed by hacker ID.
SQL Query
SELECT
h.hacker_id,
h.name,
COUNT(DISTINCT c.challenge_id) AS challengesCount
FROM
Challenges c
JOIN
Hackers h ON c.hacker_id = h.hacker_id
GROUP BY
h.hacker_id, h.name
HAVING
-- Check if the hacker's challenge count is the maximum
COUNT(DISTINCT c.challenge_id) = (
SELECT MAX(ChallengeCount)
FROM (
SELECT COUNT(DISTINCT challenge_id) AS ChallengeCount
FROM Challenges
GROUP BY hacker_id
) AS SubMax
)
-- OR check if the hacker's challenge count is unique
OR COUNT(DISTINCT c.challenge_id) IN (
SELECT ChallengeCount
FROM (
SELECT COUNT(DISTINCT challenge_id) AS ChallengeCount
FROM Challenges
GROUP BY hacker_id
) AS SubUnique
GROUP BY ChallengeCount
HAVING COUNT(*) = 1
)
ORDER BY
COUNT(DISTINCT c.challenge_id) DESC, h.hacker_id;