runtime
45 / 88

lesson 45 Window functions · advanced

Top N per group & ties

Find the leading records within each group and handle ties.

the idea

Top-N per group = rank within each group, then filter. DENSE_RANK keeps every player at the top N distinct values, ties included; ROW_NUMBER keeps exactly N rows per group and needs a tie-breaker to decide who is cut.

Dataset: Sports

The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.

games13 columns · 23,168 rows
game_idtext · unique idseasonnumber · links to seasonsgame_datedategame_numbernumbergame_typetextvenue_idtext · links to venueshome_team_idtext · links to teamsaway_team_idtext · links to teamshome_scorenumberaway_scorenumberday_nighttextattendancenumberduration_minutesnumber
ANA20160404020162016-04-040regularANA01ANACHN09night44020188
ANA20160405020162016-04-050regularANA01ANACHN16night37042154
ANA20160407020162016-04-070regularANA01ANATEX43night39089191
ANA20160408020162016-04-080regularANA01ANATEX37night35207210
ANA20160409020162016-04-090regularANA01ANATEX14night38106173
ANA20160410020162016-04-100regularANA01ANATEX31day35097163
game_idtext · unique id
ANA201604040
seasonnumber · links to seasons
2016
game_datedate
2016-04-04
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
CHN
home_scorenumber
0
away_scorenumber
9
day_nighttext
night
attendancenumber
44020
duration_minutesnumber
188
game_idtext · unique id
ANA201604050
seasonnumber · links to seasons
2016
game_datedate
2016-04-05
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
CHN
home_scorenumber
1
away_scorenumber
6
day_nighttext
night
attendancenumber
37042
duration_minutesnumber
154
game_idtext · unique id
ANA201604070
seasonnumber · links to seasons
2016
game_datedate
2016-04-07
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
TEX
home_scorenumber
4
away_scorenumber
3
day_nighttext
night
attendancenumber
39089
duration_minutesnumber
191
game_idtext · unique id
ANA201604080
seasonnumber · links to seasons
2016
game_datedate
2016-04-08
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
TEX
home_scorenumber
3
away_scorenumber
7
day_nighttext
night
attendancenumber
35207
duration_minutesnumber
210
game_idtext · unique id
ANA201604090
seasonnumber · links to seasons
2016
game_datedate
2016-04-09
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
TEX
home_scorenumber
1
away_scorenumber
4
day_nighttext
night
attendancenumber
38106
duration_minutesnumber
173
game_idtext · unique id
ANA201604100
seasonnumber · links to seasons
2016
game_datedate
2016-04-10
game_numbernumber
0
game_typetext
regular
venue_idtext · links to venues
ANA01
home_team_idtext · links to teams
ANA
away_team_idtext · links to teams
TEX
home_scorenumber
3
away_scorenumber
1
day_nighttext
day
attendancenumber
35097
duration_minutesnumber
163

first 6 of 23,168 rows · your queries use all of them

player_game_stats17 columns · 73,029 rows
game_idtext · links to gamesplayer_idtext · links to playersteam_idtext · links to teamsbatting_ordernumberstartednumberplate_appearancesnumberat_batsnumberrunsnumberhitsnumberdoublesnumbertriplesnumberhome_runsnumberrbinumberwalksnumberstrikeoutsnumberstolen_basesnumberhit_by_pitchnumber
ANA202504040adelj001ANA81550210030200
ANA202504040andet001ANA40110000000000
ANA202504040ariag002CLE81421100002000
ANA202504040clase001CLENULL0000000000000
ANA202504040danac001ANANULL0000000000000
ANA202504040darnt001ANA90110000000000
game_idtext · links to games
ANA202504040
player_idtext · links to players
adelj001
team_idtext · links to teams
ANA
batting_ordernumber
8
startednumber
1
plate_appearancesnumber
5
at_batsnumber
5
runsnumber
0
hitsnumber
2
doublesnumber
1
triplesnumber
0
home_runsnumber
0
rbinumber
3
walksnumber
0
strikeoutsnumber
2
stolen_basesnumber
0
hit_by_pitchnumber
0
game_idtext · links to games
ANA202504040
player_idtext · links to players
andet001
team_idtext · links to teams
ANA
batting_ordernumber
4
startednumber
0
plate_appearancesnumber
1
at_batsnumber
1
runsnumber
0
hitsnumber
0
doublesnumber
0
triplesnumber
0
home_runsnumber
0
rbinumber
0
walksnumber
0
strikeoutsnumber
0
stolen_basesnumber
0
hit_by_pitchnumber
0
game_idtext · links to games
ANA202504040
player_idtext · links to players
ariag002
team_idtext · links to teams
CLE
batting_ordernumber
8
startednumber
1
plate_appearancesnumber
4
at_batsnumber
2
runsnumber
1
hitsnumber
1
doublesnumber
0
triplesnumber
0
home_runsnumber
0
rbinumber
0
walksnumber
2
strikeoutsnumber
0
stolen_basesnumber
0
hit_by_pitchnumber
0
game_idtext · links to games
ANA202504040
player_idtext · links to players
clase001
team_idtext · links to teams
CLE
batting_ordernumber
NULL
startednumber
0
plate_appearancesnumber
0
at_batsnumber
0
runsnumber
0
hitsnumber
0
doublesnumber
0
triplesnumber
0
home_runsnumber
0
rbinumber
0
walksnumber
0
strikeoutsnumber
0
stolen_basesnumber
0
hit_by_pitchnumber
0
game_idtext · links to games
ANA202504040
player_idtext · links to players
danac001
team_idtext · links to teams
ANA
batting_ordernumber
NULL
startednumber
0
plate_appearancesnumber
0
at_batsnumber
0
runsnumber
0
hitsnumber
0
doublesnumber
0
triplesnumber
0
home_runsnumber
0
rbinumber
0
walksnumber
0
strikeoutsnumber
0
stolen_basesnumber
0
hit_by_pitchnumber
0
game_idtext · links to games
ANA202504040
player_idtext · links to players
darnt001
team_idtext · links to teams
ANA
batting_ordernumber
9
startednumber
0
plate_appearancesnumber
1
at_batsnumber
1
runsnumber
0
hitsnumber
0
doublesnumber
0
triplesnumber
0
home_runsnumber
0
rbinumber
0
walksnumber
0
strikeoutsnumber
0
stolen_basesnumber
0
hit_by_pitchnumber
0

first 6 of 73,029 rows · your queries use all of them

worked example

Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.

  1. Pick one hits leader per team. Run this. After summing hits by player, ROW_NUMBER() = 1 keeps a single top hitter per team, breaking ties with the smaller player_id.

    step-1.sql
    SELECT team_id, player_id, hits
    FROM (
      SELECT
        s.team_id,
        s.player_id,
        SUM(s.hits) AS hits,
        ROW_NUMBER() OVER (PARTITION BY s.team_id ORDER BY SUM(s.hits) DESC, s.player_id) AS rn
      FROM player_game_stats s
      JOIN games g ON g.game_id = s.game_id
      WHERE g.game_type = 'regular'
      GROUP BY s.team_id, s.player_id
    )
    WHERE rn = 1;
  2. Find tied home-run totals. Run this. Groups with more than one player show why DENSE_RANK keeps every tied name when you ask for “top two totals.”

    step-2.sql
    SELECT team_id, home_runs, COUNT(*) AS players
    FROM (
      SELECT s.team_id, s.player_id, SUM(s.home_runs) AS home_runs
      FROM player_game_stats s
      JOIN games g ON g.game_id = s.game_id
      WHERE g.game_type = 'regular'
      GROUP BY s.team_id, s.player_id
    )
    WHERE home_runs > 15
    GROUP BY team_id, home_runs
    HAVING COUNT(*) > 1;
  3. Put it together. The lesson's pattern in one query.the pattern

    example.sql
    SELECT team_id, player_id, hits
    FROM (
      SELECT
        s.team_id,
        s.player_id,
        SUM(s.hits) AS hits,
        ROW_NUMBER() OVER (PARTITION BY s.team_id ORDER BY SUM(s.hits) DESC, s.player_id) AS rn
      FROM player_game_stats s
      JOIN games g ON g.game_id = s.game_id
      WHERE g.game_type = 'regular'
      GROUP BY s.team_id, s.player_id
    )
    WHERE rn = 1;

common mistake

LIMIT applies to the whole result, not to each team.

challenge 1

For the 2025 regular season, return team_id, player_id and home_runs for each team’s players at the team’s top two distinct home-run totals (including all ties).

Count only players with at least one home run for the team.

what to return

Columns
team_idplayer_idhome_runs in this order
Rows
any order
challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.
Top N per group & ties — Window functions · Runtime