@@ -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