Kathuko › SQL › Part 4: Subqueries and WITH

4.5 19c+

Practice: three subquery problems

Three questions where a query needs another query. Expected rows first, answers behind a tap. Read the line, then play the shot.

1. The player of the match from the beaten side?

In how many matches was the player of the match on the winning team, the losing team, or neither (a tie)?

Expected result · 2 rows
SIDEMATCHES
tie1
winning team31
Try itShow the answer
select side, count(*) as matches
from   (select case when m.winner_id is null then 'tie'
                    when (select p.team_id from cr_players p where p.player_id = m.player_of_match_id) = m.winner_id
                         then 'winning team'
                    else 'losing team' end as side
        from   cr_matches m)
group  by side
order  by side;
select case when m.winner_id is null then 'tie'
            when p.team_id = m.winner_id then 'winning team'
            else 'losing team' end as side,
       count(*) as matches
from   cr_matches m
join   cr_players p on p.player_id = m.player_of_match_id
group  by case when m.winner_id is null then 'tie'
               when p.team_id = m.winner_id then 'winning team'
               else 'losing team' end
order  by side;

Our simulator only ever gives the award to someone on the winning side, which is why the losing team never appears. Real leagues are kinder to heroic losers.

2. The season's best bowling spells

For each season, the bowler with the most wickets in a single match (ties: fewest runs conceded, then earlier match). Season, bowler, match, wickets, runs.

Expected result · 2 rows
SEASONPLAYER_NAMEMATCH_IDWICKETSRUNS
2025Haris Raza7423
2026Jack Mercer32519
Try itShow the answer
with spells as (
  select b.season, p.player_name, b.match_id,
         sum(b.is_bowler_wicket) as wickets,
         sum(b.runs_batter + case when b.extra_type in ('WD', 'NB') then b.runs_extras else 0 end) as runs
  from   cr_balls_v b
  join   cr_players p on p.player_id = b.bowler_id
  group  by b.season, p.player_name, b.match_id
)
select season, player_name, match_id, wickets, runs
from   (select s.*, row_number() over (partition by season order by wickets desc, runs, match_id) as rn
        from   spells s)
where  rn = 1
order  by season;
with spells as (
  select b.season, p.player_name, b.match_id,
         sum(b.is_bowler_wicket) as wickets,
         sum(b.runs_batter + case when b.extra_type in ('WD', 'NB') then b.runs_extras else 0 end) as runs
  from   cr_balls_v b
  join   cr_players p on p.player_id = b.bowler_id
  group  by b.season, p.player_name, b.match_id
)
select s.season, s.player_name, s.match_id, s.wickets, s.runs
from   spells s
where  not exists (select 1 from spells x
                   where  x.season = s.season
                   and   (x.wickets > s.wickets
                          or (x.wickets = s.wickets and x.runs < s.runs)
                          or (x.wickets = s.wickets and x.runs = s.runs and x.match_id < s.match_id)))
order  by s.season;

The second answer says "there's no better spell in the same season", with "better" spelled out as the same tie-breaking rules. If two spells tied on everything (same match too), it would return both.

3. Matches with a hundred

The matches in which someone scored a century: season, match, batter, runs.

Expected result · 2 rows
SEASONMATCH_IDPLAYER_NAMERUNS
20253Karthik Raman101
202624Harry Whitcombe132
Try itShow the answer
select season, match_id, player_name, runs
from   (select b.season, b.match_id, p.player_name, sum(b.runs_batter) as runs
        from   cr_balls_v b
        join   cr_players p on p.player_id = b.batter_id
        group  by b.season, b.match_id, p.player_name)
where  runs >= 100
order  by season, match_id;
with innings as (
  select b.season, b.match_id, b.batter_id, sum(b.runs_batter) as runs
  from   cr_balls_v b
  group  by b.season, b.match_id, b.batter_id
  having sum(b.runs_batter) >= 100
)
select i.season, i.match_id, p.player_name, i.runs
from   innings i
join   cr_players p on p.player_id = i.batter_id
order  by i.season, i.match_id;

Part 4 quiz

5 questions on all of Part 4. Get 4 right to pass. Retake it as often as you like.