Hacker Rank SQL Challenges Basic Join
Problems
- Population Census
- African Cities
- Average Population of Each Continent
- The Report
- Top Competitors
- Ollivander’s Inventory
- Challenges
- Contest Leaderboard
Population Census
Problem -> URL
Difficulty Level: Easy
Pseudocode:
- Join
city
andcountry
table oncity.countrycode
equal tocountry.code
.- Filter
country.continent
equal to ‘asia’.- Aggregate sum of
city.population
.Solution:
SELECT SUM(ct.population) AS sum_of_population FROM city ct INNER JOIN country cn ON ct.countrycode = cn.code WHERE LOWER(cn.continent) = 'asia';
African Cities
Problem -> URL
Difficulty Level: Easy
Pseudocode:
- Join
city
andcountry
table oncity.countrycode
equal tocountry.code
.- Filter
country.continent
equal to ‘africa’.- Select only
city.name
.Solution:
SELECT ct.name FROM city ct INNER JOIN country cn ON ct.countrycode = cn.code WHERE LOWER(cn.continent) = 'africa';
Average Population of Each Continent
Problem -> URL
Difficulty Level: Easy
Pseudocode:
- Join
city
andcountry
table oncity.countrycode
equal tocountry.code
.- Group By
country.continent
.- Aggregate
AVG(city.population)
andROUND
down to nearest integer.Solution:
SELECT cn.continent, FLOOR(AVG(ct.population)) AS avg_population FROM city ct INNER JOIN country cn ON ct.countrycode = cn.code GROUP BY cn.continent;
The Report
Problem -> URL
Difficulty Level: Medium
Pseudocode:
- Join
students
andgrades
table onstudents.marks
betweengrades.min_mark
andgrades.max_mark
.- In select, apply case clause for
students.name
.- Order By
grades.grade
descending,students.name
ascending and apply case clause wheregrades.grade
< 8 to order the results bystudents.marks
.Solution:
SELECT CASE WHEN g.grade < 8 THEN NULL ELSE s.name END AS name, g.grade, s.marks FROM students s INNER JOIN grades g ON s.marks between g.min_mark and g.max_mark ORDER BY g.grade DESC, s.name ASC, CASE WHEN g.grade < 8 THEN s.marks END ASC;
Top Competitors
Problem -> URL
Difficulty Level: Medium
Pseudocode:
- Joins
difficulty
table withchallenges
ondifficulty_level
.challenges
table withsubmissions
onchallenge_id
.submissions
table withhackers
onhacker_id
.- Group by
hacker_id
,name
having count of challenges greater than 1.- Select
hacker_id
,name
and aggregated value forcount_of_challenges
- Select
hacker_id
andname
from the subquery.- Order the result by
count_of_challenges
in descending andhacker_id
in ascending order.Solution:
SELECT t.hacker_id, t.name FROM ( SELECT h.hacker_id, h.name, COUNT(DISTINCT s.challenge_id) AS count_of_challenges FROM difficulty d INNER JOIN challenges c ON d.difficulty_level = c.difficulty_level INNER JOIN submissions s ON c.challenge_id = s.challenge_id AND s.score = d.score LEFT JOIN hackers h ON s.hacker_id = h.hacker_id GROUP BY h.hacker_id, h.name HAVING COUNT(DISTINCT s.challenge_id) > 1 ) t ORDER BY t.count_of_challenges DESC, t.hacker_id;
Ollivander’s Inventory
Problem -> URL
Difficulty Level: Medium
Pseudocode:
- Join
wands
andwands_property
oncode
.- Filter no_evil wands,
wands_property.is_evil
equal to 0.- Assign
ROW_NUMBER()
for resultant rowsPARTITION BY wands.power, wands_property.age ORDER BY wands.coins_needed ASC
. By this way we will get minimum number of gold galleons needed to buy each non-evil wand of high power and age.- Select the id, age, coins_needed, power from sub-query and filter
row_num
equal to 1.- Order the result by
power
andage
both in descending order.Solution:
SELECT t.id, t.age, t.coins_needed, t.power FROM ( SELECT w.id, wp.age, w.coins_needed, w.power, ROW_NUMBER() OVER(PARTITION BY w.power, wp.age ORDER BY w.coins_needed) AS row_num FROM wands w INNER JOIN wands_property wp ON w.code = wp.code WHERE wp.is_evil = 0 ) t WHERE t.row_num = 1 ORDER BY t.power DESC, t.age DESC;
Challenges
Problem -> URL
Difficulty Level: Medium
Pseudocode:
Create temporary viewtotal_challenges
,
- Join
hackers
andchallenges
onhacker_id
column.- Select
hacker.hacker_id
andhacker.name
.- Aggregate count of challenges for every hacker.
- Group By
hacker.hacker_id
andhacker.name
.Create temporary view
required_ids
,
- To handle
If more than one student created the same number of challenges and the count is less than the maximum number of challenges
condition we will create arequired_ids
temporary view.- Select hacker_id from
total_challenges
.- Using case clause we will create column
required
. Conditionchallenges_created
by the hacker is not equal tomax_challenges
created by hackers andcount of hackers
with same number of challenges is greater than 1 then we don’t need to include those hackers in our final result.- Basically, we will assign 1 to
required
if we want to include those hackers in our final result else 0.Finally,
- Join
total_challenges
andrequired_ids
onhacker_id
column.- Filter
required_ids.required
equal to 1.- Select
hacker_id
,name
andchallenges_created
fromtotal_challenges
.- Order the result by
total_challenges.hacker_id
in descending order andtotal_challenges.hacker_id
in ascending order.Solution:
WITH total_challenges AS ( SELECT h.hacker_id, h.name, COUNT(1) AS challenges_created FROM hackers h INNER JOIN challenges c ON h.hacker_id = c.hacker_id GROUP BY h.hacker_id, h.name ), required_ids AS ( SELECT hacker_id, CASE WHEN challenges_created != MAX(challenges_created) OVER() AND COUNT(1) OVER(PARTITION BY challenges_created) > 1 THEN 0 ELSE 1 END AS required FROM total_challenges ) SELECT t.hacker_id, t.name, t.challenges_created FROM total_challenges t INNER JOIN required_ids r ON t.hacker_id = r.hacker_id WHERE r.required = 1 ORDER BY t.challenges_created DESC, t.hacker_id;
Contest Leaderboard
Problem -> URL
Difficulty Level: Medium
Pseudocode:
Create temporary viewmax_hacker_score
,
- Select
hacker_id
,challenge_id
from submissions.- Aggregate max of score for each
hacker_id
andchallenge_id
.- Group By
hacker_id
andchallenge_id
.Create temporary view
total_scores
,
- Join
hackers
andmax_hacker_score
onhacker_id
.- Select
hackers.hacker_id
,hacker.name
fromhackers
.- Aggregate sum of scores for each hacker.
- Group by
hackers.hacker_id
andhackers.name
and having sum greater than 0.Finally,
- Select
hacker_id
,name
andtotal_score
fromtotal_scores
.- Order the result by
total_score
in descending order andhacker_id
in ascending order.Solution:
WITH max_hacker_score AS ( SELECT hacker_id, challenge_id, max(score) AS max_score FROM submissions GROUP BY hacker_id, challenge_id ), total_scores AS ( SELECT h.hacker_id, h.name, SUM(m.max_score) AS total_score FROM hackers h INNER JOIN max_hacker_score m ON h.hacker_id = m.hacker_id GROUP BY h.hacker_id, h.name HAVING SUM(m.max_score) > 0 ) SELECT t.hacker_id, t.name, t.total_score FROM total_scores t ORDER BY t.total_score DESC, t.hacker_id ASC;