Three questions, each needing the right kind of join. Expected rows first, answers behind a tap. Like a good partnership, it's all about calling clearly.
1. How Karthik Raman got out
Every time Karthik Raman was dismissed, in both seasons: the match, the ball, how he was out, and the bowler who got the credit (empty for a run out, which isn't the bowler's wicket).
| MATCH_ID | OVER_BALL | WICKET_KIND | BOWLER |
|---|---|---|---|
| 3 | 18.3 | caught | Nikhil Rao |
| 5 | 6.6 | lbw | Zubair Lodhi |
| 13 | 7.3 | run out | null |
| 16 | 16.4 | lbw | Andile Zulu |
| 19 | 5.1 | bowled | Kemar Joseph |
| 22 | 8.3 | run out | null |
| 23 | 2.1 | lbw | Callum Reid |
| 30 | 0.1 | caught | Kyle Fourie |
| 32 | 2.1 | caught | Tom Blackwood |
Try itShow the answer
select b.match_id, b.over_ball, b.wicket_kind, bw.player_name as bowler
from cr_balls_v b
join cr_players po on po.player_id = b.player_out_id
left join cr_players bw on bw.player_id = b.bowler_id and b.is_bowler_wicket = 1
where po.player_name = 'Karthik Raman'
order by b.match_id;
select b.match_id, b.over_ball, b.wicket_kind,
case when b.is_bowler_wicket = 1
then (select bw.player_name from cr_players bw where bw.player_id = b.bowler_id)
end as bowler
from cr_balls_v b
where b.player_out_id = (select player_id from cr_players where player_name = 'Karthik Raman')
order by b.match_id;
The trick in the first answer: and b.is_bowler_wicket = 1 sits in the ON of the LEFT JOIN, so
for a run out the join finds no bowler and leaves null, while the row itself survives.
2. Bowlers who never bowled
Players with a bowling style who didn't bowl a single ball in either season. Team code, name, style.
| PLAYER_NAME | TEAM_CODE | BOWLING_STYLE |
|---|---|---|
| Blair Hollis | AKL | Right-arm fast-medium |
| Connor Wallace | AKL | Right-arm fast-medium |
| Ashwath Krishnan | CHN | Right-arm fast |
| Rahul Menon | CHN | Right-arm medium |
| Johan Kruger | DBN | Right-arm medium |
| Lwazi Dube | DBN | Right-arm fast-medium |
| Saad Butt | KHI | Right-arm medium |
| Talha Aziz | KHI | Right-arm fast-medium |
| Ben Oakes | LDS | Right-arm fast-medium |
| George Pembury | LDS | Right-arm off-spin |
| Dwayne Charles | TPA | Right-arm medium |
| Liam Foster | TPA | Right-arm fast-medium |
| Shane McAllister | TPA | Right-arm fast-medium |
Try itShow the answer
select p.player_name, t.team_code, p.bowling_style
from cr_players p
join cr_teams t on t.team_id = p.team_id
where p.bowling_style is not null
and not exists (select 1 from cr_deliveries d where d.bowler_id = p.player_id)
order by t.team_code, p.player_name;
select p.player_name, t.team_code, p.bowling_style
from cr_players p
join cr_teams t on t.team_id = p.team_id
left join (select distinct bowler_id from cr_deliveries) d on d.bowler_id = p.player_id
where p.bowling_style is not null
and d.bowler_id is null
order by t.team_code, p.player_name;
Each team uses five front-line bowlers, so the other bowlers in the squad carry their bowling boots around all season for nothing.
3. Who did Chennai beat?
The teams Chennai beat in 2026 and how: match, opponent, win type and margin.
| MATCH_ID | OPPONENT | WIN_TYPE | WIN_MARGIN |
|---|---|---|---|
| 17 | Karachi Kites | WICKETS | 7 |
| 19 | Tampa Tides | RUNS | 10 |
| 22 | Auckland Albatross | WICKETS | 7 |
| 30 | Durban Dhows | WICKETS | 6 |
Try itShow the answer
select m.match_id, o.team_name as opponent, m.win_type, m.win_margin
from cr_matches m
join cr_teams o on o.team_id = case when m.home_team_id = 2 then m.away_team_id
else m.home_team_id end
where m.season = 2026
and m.winner_id = 2
order by m.match_id;
select m.match_id, o.team_name as opponent, m.win_type, m.win_margin
from cr_matches m
join cr_teams o on o.team_id in (m.home_team_id, m.away_team_id) and o.team_id <> 2
where m.season = 2026
and m.winner_id = 2
order by m.match_id;
A join condition can be any expression: a CASE that picks "the other team", or an IN list plus
"not Chennai". Both pick exactly one opponent per match.
Part 2 quiz
5 questions on all of Part 2. Get 4 right to pass. Retake it as often as you like.