Skip to content

Commit 26550dd

Browse files
committed
feat: add win streak column to ELO leaderboard
Add a win_streak CTE to queryElo() that computes each player's current consecutive win streak from finished matches, respecting time window, match type, and tournament exclusion filters. Maps result to tertiary_value on LeaderboardEntry.
1 parent 7d24a29 commit 26550dd

1 file changed

Lines changed: 60 additions & 2 deletions

File tree

src/leaderboard/leaderboard.controller.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,21 @@ export class LeaderboardController {
199199
: "";
200200
if (windowDays > 0) params.push(windowDays);
201201

202+
const streakMatchTypeFilter = matchType
203+
? `AND mo.type = $${paramIdx++}`
204+
: "";
205+
if (matchType) params.push(matchType);
206+
207+
const streakTimeFilter =
208+
windowDays > 0
209+
? `AND m.ended_at >= NOW() - make_interval(days => $${paramIdx++})`
210+
: "";
211+
if (windowDays > 0) params.push(windowDays);
212+
213+
const streakTournamentFilter = excludeTournaments
214+
? this.tournamentExclusionFilter("m.id")
215+
: "";
216+
202217
params.push(MAX_RESULTS);
203218
const limitParam = `$${paramIdx++}`;
204219

@@ -243,6 +258,27 @@ export class LeaderboardController {
243258
${timeFilter}
244259
${this.tournamentExclusionFilter("pe.match_id")}
245260
GROUP BY pe.steam_id
261+
),
262+
win_streak AS (
263+
SELECT sub.steam_id,
264+
COALESCE(MIN(CASE WHEN sub.won = 0 THEN sub.rn END) - 1, MAX(sub.rn))::int as streak
265+
FROM (
266+
SELECT
267+
mlp.steam_id,
268+
CASE WHEN m.winning_lineup_id = mlp.match_lineup_id THEN 1 ELSE 0 END as won,
269+
ROW_NUMBER() OVER (PARTITION BY mlp.steam_id ORDER BY m.ended_at DESC) as rn
270+
FROM match_lineup_players mlp
271+
JOIN match_lineups ml ON ml.id = mlp.match_lineup_id
272+
JOIN matches m ON (m.lineup_1_id = ml.id OR m.lineup_2_id = ml.id)
273+
JOIN match_options mo ON mo.id = m.match_options_id
274+
WHERE m.status = 'Finished'
275+
AND mlp.steam_id IS NOT NULL
276+
AND m.winning_lineup_id IS NOT NULL
277+
${streakTimeFilter}
278+
${streakMatchTypeFilter}
279+
${streakTournamentFilter}
280+
) sub
281+
GROUP BY sub.steam_id
246282
)
247283
SELECT
248284
le.steam_id,
@@ -251,12 +287,13 @@ export class LeaderboardController {
251287
p.country,
252288
le.raw_current - COALESCE(ta.tourney_total, 0) as value,
253289
(le.raw_current - COALESCE(ta.tourney_total, 0)) - fe.starting_elo as secondary_value,
254-
NULL as tertiary_value,
290+
COALESCE(ws.streak, 0) as tertiary_value,
255291
COALESCE(mc.matches_played, 0) as matches_played
256292
FROM last_elo_raw le
257293
LEFT JOIN tournament_adj ta ON ta.steam_id = le.steam_id
258294
JOIN first_elo fe ON fe.steam_id = le.steam_id
259295
LEFT JOIN match_counts mc ON mc.steam_id = le.steam_id
296+
LEFT JOIN win_streak ws ON ws.steam_id = le.steam_id
260297
JOIN players p ON p.steam_id = le.steam_id
261298
ORDER BY value DESC
262299
LIMIT ${limitParam}
@@ -290,6 +327,26 @@ export class LeaderboardController {
290327
${eloTypeFilter}
291328
${timeFilter}
292329
GROUP BY pe.steam_id
330+
),
331+
win_streak AS (
332+
SELECT sub.steam_id,
333+
COALESCE(MIN(CASE WHEN sub.won = 0 THEN sub.rn END) - 1, MAX(sub.rn))::int as streak
334+
FROM (
335+
SELECT
336+
mlp.steam_id,
337+
CASE WHEN m.winning_lineup_id = mlp.match_lineup_id THEN 1 ELSE 0 END as won,
338+
ROW_NUMBER() OVER (PARTITION BY mlp.steam_id ORDER BY m.ended_at DESC) as rn
339+
FROM match_lineup_players mlp
340+
JOIN match_lineups ml ON ml.id = mlp.match_lineup_id
341+
JOIN matches m ON (m.lineup_1_id = ml.id OR m.lineup_2_id = ml.id)
342+
JOIN match_options mo ON mo.id = m.match_options_id
343+
WHERE m.status = 'Finished'
344+
AND mlp.steam_id IS NOT NULL
345+
AND m.winning_lineup_id IS NOT NULL
346+
${streakTimeFilter}
347+
${streakMatchTypeFilter}
348+
) sub
349+
GROUP BY sub.steam_id
293350
)
294351
SELECT
295352
le.steam_id,
@@ -298,11 +355,12 @@ export class LeaderboardController {
298355
p.country,
299356
le.current_elo as value,
300357
le.current_elo - fe.starting_elo as secondary_value,
301-
NULL as tertiary_value,
358+
COALESCE(ws.streak, 0) as tertiary_value,
302359
mc.matches_played
303360
FROM last_elo le
304361
JOIN first_elo fe ON fe.steam_id = le.steam_id
305362
JOIN match_counts mc ON mc.steam_id = le.steam_id
363+
LEFT JOIN win_streak ws ON ws.steam_id = le.steam_id
306364
JOIN players p ON p.steam_id = le.steam_id
307365
ORDER BY value DESC
308366
LIMIT ${limitParam}

0 commit comments

Comments
 (0)